I am recording audio from getUserMedia({audio:true});
in the browser using Recorder.js and then exporting it as a WAV file because that's the only option the library provides.
A 1 minute 20 seconds file is 14.1 MB large. I need to upload the audio to a server and I need to do it fast. How do I convert the WAV audio in any other compressed format to lower the file size?
I don't mind converting to:
- MP3
- Opus
- WebM
- Ogg
- FLAC
- any other format you know of
If there is no way as of now to convert to any of these formats, how can I compress the WAV file on the client?
PS: I did a lot of searches to find anything that converts WAV in JS, but found nothing. libmp3lame.js isn't working in Chrome.
Thanks!
I've made an audio recorder that records to mp3 directly from the browser combining RecorderJS and libmp3lame.js
You can find the gitHub project here:
https://github.com/nusofthq/Recordmp3js
and a more detailed explanation of the implementation:
http://nusofthq.com/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/
What you really want is the mediaStream "Recording API", which is currently being worked on. Until that's available, I advise using emscriptem on C/C++ source, and consider running it in a webworker to avoid blocking the UI and other tabs.
I was facing the same problem and
came up with quite a quick and dirty solution:
- zip the wav-file with zip.js (works with Chrome, Firefox, Safari 6 and Internet Explorer 10)
Further intel see Documentation zip.js
At least this is reducing size a lot, file is about >75% smaller so 1:4 compression
UPDATE: Maybe have a look at this: https://webrtc.github.io/samples/
It is a Chat Application for Chrome and Firefox developed by google, I assume with kind of CC-License
I had a similar issue (also using recorder.js) and have managed to resolve using the superb videoconverter.js project which includes a port of ffmpeg to Javascript using emscripen. Downside to this is the ffmpeg.js file is about 25Mb.
I modified the existing exportWAV
function in recorderWorker.js to return both a WAV (for HTML5 <audio>
playback) and a Blob containing an encoded MP2 file:
function encodeWAV(samples) {
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer);
/* ... various writing methods */
return { wavdata: new Blob([buffer], { type: "audio/wav" }), mp2data: ffmpeg_convert(buffer) };
}
function ffmpeg_convert(buffer) {
console.log("starting mp2 conversion");
var args = "-i input -f mp2 output.mp2";
var results = ffmpeg_run({
arguments: args.split(" "),
files: [
{
data: new Uint8Array(buffer),
"name": "input"
}
]
});
if (results) {
var file = results[0];
console.log("File recieved", file.name, file.data);
return new Blob([file.data], { type: "audio/mpeg" });
}
return null;
}
This method can be used to encode the WAV to any codec suppored by ffmpeg's libavcodec
I was able to achieve compression using opus.js,
you can find my implementation here: recordOpus, but there is a catch, mine is coupled with server-side, and I use node.js
server....