Reputation: 34556
I have a screen recorder web extension that generates the recorded video as a download. Everything's fine in Chrome, but none of the generated videos are playing in Firefox.
I've tried both .webm (via the VP9 codec) and .mp4 (via H264). The pertinent code is:
recorder.addEventListener('stop', evt => {
blob = new Blob(recorder.chunks, {'type': 'video/webm; codecs=vp9'});
blob_url = window.URL.createObjectURL(blob);
//...
Also tried
{'type': 'video/mp4; codecs=H264'}
In Firefox I just see:
What am I doing wrong?
[EDIT]
Following @epistemex's helpful answer I am now specifying webm at the point of creating the MediaRecorder
, and not specifying any codec.
MediaRecorder(master_stream, {mimeType: 'video/webm'});
Then later
blob = new Blob(recorder.chunks); //<-- not setting mime here now
...but still Firefox says it can't play the resultant files, even though
MediaRecorder.isTypeSupported("video/webm") //true
[EDIT 2 - including more code]
if (rec_prefs.rec_vid == 'screen') listen_for_stop_screen_sharing();
recorder = new MediaRecorder(master_stream, {mimeType: 'video/webm'});
recorder.start();
recorder.chunks = [];
recorder.addEventListener('dataavailable', evt => {
recorder.chunks.push(evt.data);
}, false);
rec_stopped_dfd = new Promise((resolve) => {
recorder.addEventListener('stop', evt => {
blob = new Blob(recorder.chunks);
blob_url = window.URL.createObjectURL(blob);
resolve();
}, false);
});
Call to recorder.stop()
is in a callback in response to a button click:
function stop_recording() {
master_stream.getTracks().forEach(track => track.stop());
if (recorder && recorder.state != 'inactive') {
recorder.stop();
Yes I can confirm the array is not empty. Everything works perfectly in Chrome - no errors, console etc.
Upvotes: 3
Views: 1757
Reputation:
Firefox doesn't support audio/webm using the vp9 codec, nor MP4 containers where data is encoded using H.264 (this may be related to licensing/legal aspects).
You can test support using the MediaRecorder.isTypeSupported()
to check for support:
console.log("video/webm: ", MediaRecorder.isTypeSupported("video/webm"))
console.log("video/webm; codecs=vp9: ", MediaRecorder.isTypeSupported("video/webm; codecs=vp9"))
console.log("video/mp4; codecs=H264: ", MediaRecorder.isTypeSupported("video/mp4; codecs=H264"))
The other thing you need to be aware of that is that setting the mime-type for the Blob does not affect the data itself in any form - that is just metadata. You have to specify the mime-type in the option object for the MediaRecorder
(you don't show this part in the question so you may do this already, but just in case if not):
const mediaRecorder = new MediaRecorder(stream, {
mimeType: "video/webm"
});
So what to do: well, if not supported it's really not much you can do, except from using a codec that is supported. You can simply leave out the more specific vp9 requirement and let the browser determine what to use, or use a simplified fallback, for example:
const mime = MediaRecorder.isTypeSupported("video/webm; codecs=vp9")
? "video/webm; codecs=vp9"
: "video/webm"; // here: assumed support (todo)
const mediaRecorder = new MediaRecorder(stream, {
mimeType: mime
});
Hope this helps!
Upvotes: 4