Skip to content

Instantly share code, notes, and snippets.

@channyeintun
Created October 27, 2023 16:47
Show Gist options
  • Save channyeintun/4ffb0a271b61126ae1348ebf4d71941a to your computer and use it in GitHub Desktop.
Save channyeintun/4ffb0a271b61126ae1348ebf4d71941a to your computer and use it in GitHub Desktop.
Encode microphone audio to flac format in React.js
// 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