为什么我的JS生成的视频不能在Firefox中播放?

时间:2018-09-11 18:46:29

标签: javascript firefox html5-video mp4 webm

我有一个屏幕录像机Web扩展程序,可以将录制的视频下载下来。在Chrome浏览器中一切正常,但生成的所有视频都无法在Firefox中播放。

我已经尝试了.webm(通过VP9编解码器)和.mp4(通过H264)。相关代码为:

recorder.addEventListener('stop', evt => {
    blob = new Blob(recorder.chunks, {'type': 'video/webm; codecs=vp9'});
    blob_url = window.URL.createObjectURL(blob);
    //...

也尝试过

{'type': 'video/mp4; codecs=H264'}

在Firefox中,我只会看到:

enter image description here

我在做什么错了?

[编辑]

在@epistemex有用的回答之后,我现在在创建MediaRecorder时指定webm,而不指定任何编解码器。

MediaRecorder(master_stream, {mimeType: 'video/webm'});

然后再

blob = new Blob(recorder.chunks); //<-- not setting mime here now

...但是Firefox仍然说即使播放结果文件也无法播放

MediaRecorder.isTypeSupported("video/webm") //true

[编辑2-包括更多代码]

    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);
    });

recorder.stop()的调用是在回调中,以响应单击按钮:

function stop_recording() {
    master_stream.getTracks().forEach(track => track.stop());
    if (recorder && recorder.state != 'inactive') {
        recorder.stop();

是的,我可以确认数组不为空。一切都能在Chrome中完美运行-没有错误,控制台等。

1 个答案:

答案 0 :(得分:2)

Firefox不支持使用vp9编解码器的音频/ webm,也不支持使用H.264编码数据的MP4容器(这可能与许可/法律方面有关)。

您可以使用MediaRecorder.isTypeSupported()测试支持,以检查支持:

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"))

您需要注意的另一件事是,为 Blob 设置mime-type不会以任何形式影响数据本身-这仅仅是元数据。您必须在MediaRecorder的选项对象中指定mime-type(您没有在问题中显示此部分,因此您可能已经这样做了,但以防万一):

const mediaRecorder = new MediaRecorder(stream, {
    mimeType: "video/webm"
  });

那该怎么办:好吧,如果不支持,除了使用受支持的编解码器之外, 确实不行。您可以简单地忽略更特定的vp9要求,然后让浏览器确定要使用什么,或者使用简化的后备,例如:

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
  });

希望这会有所帮助!