npx create-react-app speech-to-text
App.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
.App { text-align: center; } .App-logo { height: 40vmin; pointer-events: none; } @media (prefers-reduced-motion: no-preference) { .App-logo { animation: App-logo-spin infinite 20s linear; } } .App-header { background-color: #282c34; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: calc(10px + 2vmin); color: white; } .App-link { color: #61dafb; } @keyframes App-logo-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } |
index.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } .container { margin: 20px; display: grid; grid-template-columns: 1fr 1fr; } .box { box-shadow: -4px 10px 35px -1px rgba(0, 0, 0, 0.75); min-height: 20rem; margin: 30px; padding: 20px; border-radius: 5px; } h1 { margin-left: 20px; } button { float: right; margin: 10px; padding: 10px; border-radius: 5px; background: transparent; } |
App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
import React, { useState, useEffect } from "react"; import "./App.css"; const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; const mic = new SpeechRecognition(); mic.continuous = true; mic.interimResults = true; mic.lang = "en-US"; function App() { const [isListening, setIsListening] = useState(false); const [note, setNote] = useState(null); const [savedNotes, setSavedNotes] = useState([]); useEffect(() => { handleListen(); }, [isListening]); const handleListen = () => { if (isListening) { mic.start(); mic.onend = () => { console.log("continue.."); mic.start(); }; } else { mic.stop(); mic.onend = () => { console.log("Stopped Mic on Click"); }; } mic.onstart = () => { console.log("Mics on"); }; mic.onresult = (event) => { const transcript = Array.from(event.results) .map((result) => result[0]) .map((result) => result.transcript) .join(""); console.log(transcript); setNote(transcript); mic.onerror = (event) => { console.log(event.error); }; }; }; const handleSaveNote = () => { setSavedNotes([...savedNotes, note]); setNote(""); }; return ( <> <h1>Voice Notes</h1> <div className="container"> <div className="box"> <h2>Current Note</h2> {isListening ? <span>🎙️</span> : <span>🛑🎙️</span>} <button onClick={handleSaveNote} disabled={!note}> Save Note </button> <button onClick={() => setIsListening((prevState) => !prevState)}> Start/Stop </button> <p>{note}</p> </div> <div className="box"> <h2>Notes</h2> {savedNotes.map((n) => ( <p key={n}>{n}</p> ))} </div> </div> </> ); } export default App; |