इस लेख में हम निम्नलिखित विषयों पर गौर करेंगे
हम रिएक्ट हुक बनाकर शुरुआत करेंगे जो स्टार्ट रिकॉर्डिंग, स्टॉप रिकॉर्डिंग, ऑडियो ब्लॉब बनाना, त्रुटि प्रबंधन आदि जैसे सभी काम करेगा।
हुक के मांस में जाने से पहले हमें कुछ अन्य बातों का ध्यान रखना होगा
const VOICE_MIN_DECIBELS = -35 const DELAY_BETWEEN_DIALOGUE = 2000
आइए अपने हुक का नाम उपयोगऑडियोइनपुट.ts रखें, हम ब्राउज़र एपीआई जैसे नेविगेटर.मीडियाडिवाइस.गेटयूजरमीडिया, मीडियारिकॉर्डर और ऑडियोकॉन्टेक्स्ट का उपयोग करेंगे। AudioContext हमें यह पहचानने में मदद करेगा कि क्या इनपुट ऑडियो न्यूनतम डेसिबल से अधिक है जो इसे इनपुट के रूप में मानने के लिए आवश्यक है, इसलिए हम निम्नलिखित वेरिएबल्स और प्रॉप्स के साथ शुरुआत करेंगे
const defaultConfig = { audio: true }; type Payload = Blob; type Config = { audio: boolean; timeSlice?: number timeInMillisToStopRecording?: number onStop: () => void; onDataReceived: (payload: Payload) => void }; export const useAudioInput = (config: Config = defaultConfig) => { const mediaChunks = useRef([]); const [isRecording, setIsRecording] = useState(false); const mediaRecorder = useRef (null); const [error, setError] = useState (null); let requestId: number; let timer: ReturnType ; const createBlob = () => { const [chunk] = mediaChunks.current; const blobProperty = { type: chunk.type }; return new Blob(mediaChunks.current, blobProperty) } ... }
उपरोक्त कोड में हम इनपुट ब्लॉब को होल्ड करने के लिए वेरिएबल के रूप में मीडियाचंक्स का उपयोग करेंगे और नए मीडियारिकॉर्डर का उदाहरण पाने के लिए मीडियारिकॉर्डर का उपयोग करेंगे जो नेविगेटर.मीडियाडिवाइसेज.गेटयूजरमीडिया से इनपुट के रूप में स्ट्रीम लेता है। अब आइए उन मामलों पर ध्यान दें जहां getUserMedia उपलब्ध नहीं है
... useEffect(() => { if(!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { const notAvailable = new Error('Your browser does not support Audio Input') setError(notAvailable) } },[]); ...
हम हुक की वास्तविक कार्यक्षमता लिखना शुरू करेंगे जिसमें सेटअपमीडियारिकॉर्डर, सेटअपऑडियोकॉन्टेक्स्ट, ऑनरिकॉर्डिंगस्टार्ट, ऑनरिकॉर्डिंगएक्टिव, स्टार्टरिकॉर्डिंग, स्टॉपरिकॉर्डिंग आदि जैसे विभिन्न फ़ंक्शन शामिल होंगे।
const onRecordingStart = () => mediaChunks.current = []; const onRecordingActive = useCallback(({data}: BlobEvent) => { if(data) { mediaChunks.current.push(data); config?.onDataReceived?.(createBlob()) } },[config]); const startTimer = () => { timer = setTimeout(() => { stopRecording(); }, config.timeInMillisToStopRecording) }; const setupMediaRecorder = ({stream}:{stream: MediaStream}) => { mediaRecorder.current = new MediaRecorder(stream) mediaRecorder.current.ondataavailable = onRecordingActive mediaRecorder.current.onstop = onRecordingStop mediaRecorder.current.onstart = onRecordingStart mediaRecorder.current.start(config.timeSlice) }; const setupAudioContext = ({stream}:{stream: MediaStream}) => { const audioContext = new AudioContext(); const audioStreamSource = audioContext.createMediaStreamSource(stream); const analyser = audioContext.createAnalyser(); analyser.minDecibels = VOICE_MIN_DECIBELS; audioStreamSource.connect(analyser); const bufferLength = analyser.frequencyBinCount; const domainData = new Uint8Array(bufferLength) return { domainData, bufferLength, analyser } }; const startRecording = async () => { setIsRecording(true); await navigator.mediaDevices .getUserMedia({ audio: config.audio }) .then((stream) => { setupMediaRecorder({stream}); if(config.timeSlice) { const { domainData, analyser, bufferLength } = setupAudioContext({ stream }); startTimer() } }) .catch(e => { setError(e); setIsRecording(false) }) }; const stopRecording = () => { mediaRecorder.current?.stop(); clearTimeout(timer); window.cancelAnimationFrame(requestId); setIsRecording(false); onRecordingStop() }; const createBlob = () => { const [chunk] = mediaChunks.current; const blobProperty = { type: chunk.type }; return new Blob(mediaChunks.current, blobProperty) } const onRecordingStop = () => config?.onStop?.();
उपरोक्त कोड के साथ हम हुक के साथ लगभग काम पूरा कर चुके हैं, एकमात्र लंबित चीज यह पहचानना है कि उपयोगकर्ता ने बोलना बंद कर दिया है या नहीं, हम DELAY_BETWEEN_DIALOGUE का उपयोग उस समय के रूप में करेंगे जिसके लिए हम प्रतीक्षा करेंगे, यदि 2 के लिए कोई इनपुट नहीं है कुछ सेकंड में हम मान लेंगे कि उपयोगकर्ता ने बोलना बंद कर दिया है और भाषण को टेक्स्ट एंडपॉइंट पर हिट कर देगा।
... const detectSound = ({ recording, analyser, bufferLength, domainData }: { recording: boolean analyser: AnalyserNode bufferLength: number domainData: Uint8Array }) => { let lastDetectedTime = performance.now(); let anySoundDetected = false; const compute = () => { if (!recording) { return; } const currentTime = performance.now(); const timeBetweenTwoDialog = anySoundDetected === true && currentTime - lastDetectedTime > DELAY_BETWEEN_DIALOGUE; if (timeBetweenTwoDialog) { stopRecording(); return; } analyser.getByteFrequencyData(domainData); for (let i = 0; i 0) { anySoundDetected = true; lastDetectedTime = performance.now(); } } requestId = window.requestAnimationFrame(compute); }; compute(); } ... const startRecording = async () => { ... detectSound() ... }
उपरोक्त कोड में हम उपयोगकर्ता ऑडियो इनपुट का पता लगाने के लिए requestAnimationFrame का उपयोग कर रहे हैं, इसके साथ हमने हुक के साथ काम पूरा कर लिया है और अब विभिन्न स्थानों पर हुक का उपयोग शुरू कर सकते हैं।
जैसे
const onDataReceived = async (data: BodyInit) => { const rawResponse = await fetch('https://backend-endpoint', { method: 'POST', body: data }); const response = await rawResponse.json(); setText(response) }; const { isRecording, startRecording, error } = useAudioInput({ audio: true, timeInMillisToStopRecording: 2000, timeSlice: 400, onDataReceived })
दूसरा भाग एक नोड सर्वर को वायर करना है जो Google भाषण से टेक्स्ट एपीआई तक संचार कर सकता है, मैंने दस्तावेज़ संलग्न किया है जिसे मैंने चीजों का नोड पक्ष बनाते समय संदर्भित किया था।
https://codelabs.developers.google.com/codelabs/cloud-speech-text-node.
// demo node server which connects with google speech to text api endpoint const express = require('express'); const cors = require('cors'); const speech = require('@google-cloud/speech'); const client = new speech.SpeechClient(); async function convert(audioBlob) { const request = { config: { encoding: 'WEBM_OPUS', // Ensure this matches the format of the audio being sent sampleRateHertz: 48000, // This should match the sample rate of your recording languageCode: 'en-US' }, audio: { content: audioBlob } }; const [response] = await client.recognize(request); const transcription = response.results .map(result => result.alternatives[0].transcript) .join('\n'); return transcription; } const app = express(); app.use(cors()) app.use(express.json()); app.post('/upload', express.raw({ type: '*/*' }), async (req, res) => { const audioBlob = req.body; const response = await convert(audioBlob); res.json(response); }); app.listen(4000,'0.0.0.0', () => { console.log('Example app listening on port 4000!'); });
इस लेख में मैंने ऑडियो सामग्री या ब्लॉब को गूगल स्पीच से टेक्स्ट एंडपॉइंट पर भेजना शामिल किया है, हम सामग्री के बजाय एक ब्लॉब यूरी भी भेज सकते हैं, केवल पेलोड में परिवर्तन होगा
// sending url as part of audio object to speech to text api ... audio: {url: audioUrl} or audio: {content: audioBlob} ...
लेख से संबंधित कोड जीथब में मौजूद है।
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3