Created
October 27, 2023 16:47
-
-
Save channyeintun/4ffb0a271b61126ae1348ebf4d71941a to your computer and use it in GitHub Desktop.
Encode microphone audio to flac format in React.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// To encode microphone audio to flac format in React.js | |
// put encoder.js, libflac3-1.3.2.min.js, libflac3-1.3.2.min.js.mem in public folder | |
// Get necessary files from https://github.com/mmig/speech-to-flac | |
export function FlacAudioRecorder({ onData }) { | |
let recording = false; | |
let stream; | |
let input; | |
let node; | |
let encoder; | |
function startRecording() { | |
if (recording) | |
return; | |
console.log('start recording');//DEBUG | |
encoder = new Worker('encoder.js'); | |
encoder.onmessage = function (e) { | |
if (e.data.cmd === 'end') { | |
console.log('e.data', e.data) | |
onData(e.data.buf); | |
encoder.terminate(); | |
encoder = null; | |
} | |
}; | |
function userMediaFailed(code) { | |
console.log('grabbing microphone failed: ' + code); | |
} | |
function gotUserMedia(localMediaStream) { | |
recording = true; | |
console.log('success grabbing microphone'); | |
stream = localMediaStream; | |
let audio_context; | |
if (typeof AudioContext !== 'undefined') { | |
audio_context = new AudioContext; | |
} else { | |
console.error('JavaScript execution environment (Browser) does not support AudioContext interface.'); | |
alert('Could not start recording audio:\n Web Audio is not supported by your browser!'); | |
return; | |
} | |
audio_context = audio_context; | |
input = audio_context.createMediaStreamSource(stream); | |
if (input.context.createJavaScriptNode) | |
node = input.context.createJavaScriptNode(4096, 1, 1); | |
else if (input.context.createScriptProcessor) | |
node = input.context.createScriptProcessor(4096, 1, 1); | |
else | |
console.error('Could not create audio node for JavaScript-based Audio Processing.'); | |
encoder.postMessage({ | |
cmd: 'init', | |
config: { | |
samplerate: 44100, | |
channels: 1, | |
bps: 16, | |
compression: 5 | |
} | |
}); | |
node.onaudioprocess = function (e) { | |
// see also: http://typedarray.org/from-microphone-to-wav-with-getusermedia-and-web-audio/ | |
let channelLeft = e.inputBuffer.getChannelData(0); | |
encoder.postMessage({ cmd: 'encode', buf: channelLeft }); | |
}; | |
input.connect(node); | |
node.connect(audio_context.destination); | |
} | |
if (navigator.webkitGetUserMedia) | |
navigator.webkitGetUserMedia({ video: false, audio: true }, gotUserMedia, userMediaFailed); | |
else if (navigator.mozGetUserMedia) | |
navigator.mozGetUserMedia({ video: false, audio: true }, gotUserMedia, userMediaFailed); | |
else | |
navigator.getUserMedia({ video: false, audio: true }, gotUserMedia, userMediaFailed); | |
} | |
function stopRecording() { | |
if (!recording) { | |
return; | |
} | |
console.log('stop recording'); | |
const tracks = stream.getAudioTracks() | |
for (let i = tracks.length - 1; i >= 0; --i) { | |
tracks[i].stop(); | |
} | |
recording = false; | |
encoder.postMessage({ cmd: 'finish' }); | |
input.disconnect(); | |
node.disconnect(); | |
input = node = null; | |
} | |
return { | |
start: startRecording, | |
stop: stopRecording, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment