webRTC使用ffmpeg.js将webm转换为mp4

q-j*_*ack 10 mp4 ffmpeg mediarecorder webrtc mediastream

我试图用ffmpeg.js将webM文件转换为mp4.我正在从画布(带有一些信息的覆盖层)录制视频并录制视频中的音频数据.

stream = new MediaStream();
var videoElem = document.getElementById('video');
var videoStream = videoElem.captureStream();
stream.addTrack(videoStream.getAudioTracks()[0]);
stream.addTrack(canvas.captureStream().getVideoTracks()[0]);
var options = {mimeType: 'video/webm'};
  recordedBlobs = [];
  mediaRecorder = new MediaRecorder(stream, options);
  mediaRecorder.onstop = handleStop;
  mediaRecorder.ondataavailable = handleDataAvailable;
  mediaRecorder.start(100); // collect 100ms of data

function handleDataAvailable(event) {
  if (event.data && event.data.size > 0) {
    recordedBlobs.push(event.data);
  }
}
mediaRecorder.stop();
Run Code Online (Sandbox Code Playgroud)

此代码按预期工作并返回webm视频

var blob = new Blob(recordedBlobs, {type: 'video/webm'});
Run Code Online (Sandbox Code Playgroud)

现在我想要一个mp4文件并检查muaz-khan 的ffmpeg.js.这些示例展示了当您有2个单一流(音频和视频)时如何转换为mp4.但我有一个带有附加音轨的流.我可以将这样的流转换为mp4吗?怎么办?

Aja*_*jay 5

根据提供的代码示例,您的记录器流仅包含一个音频和一个视频轨道。

如果您的输入文件同时具有音频和视频,则需要在此处为两个音轨指定输出编解码器,如下所示。

worker.postMessage({
    type: 'command',
    arguments: [
       '-i', 'audiovideo.webm',
       '-c:v', 'mpeg4',
       '-c:a', 'aac', // or vorbis
       '-b:v', '6400k',  // video bitrate
       '-b:a', '4800k',  // audio bitrate
       '-strict', 'experimental', 'audiovideo.mp4'
     ],
    files: [
        {
            data: new Uint8Array(fileReaderData),
            name: 'audiovideo.webm'
        }
     ]
    });
Run Code Online (Sandbox Code Playgroud)

不建议在浏览器中对视频进行转码,因为这会消耗更多的CPU时间和内存。ffmpeg_asm.js很重。可能适合POC :)

您的用例是什么?webm(vp8 / vp9)最近被广泛使用。

Chrome将支持以下MIME类型:

"video/webm"
"video/webm;codecs=vp8"
"video/webm;codecs=vp9"
"video/webm;codecs=h264"
"video/x-matroska;codecs=avc1"
Run Code Online (Sandbox Code Playgroud)

因此,您可以通过以下黑客直接从chrome MediaRecorder获取mp4录音

var options = {mimeType: 'video/webm;codecs=h264'}; 
mediaRecorder = new MediaRecorder(stream, options);
.....
//Before merging blobs change output mime 
var blob = new Blob(recordedBlobs, {type: 'video/mp4'});
// And name your file as video.mp4
Run Code Online (Sandbox Code Playgroud)

  • @Ajay“直接获取mp4录音”是什么意思?也许我犯了一些错误,但是在我的测试中,我只得到了原始的webm / h264视频,但具有不同的mime类型。因此视频容器不会改变。因此,在新的Blob(...)行之后,二进制数据完全相同,对吗?那就是我尝试过的:https://jsfiddle.net/zqd8qf6e/这里的目标不是在没有ffmpeg.js的情况下将视频容器从webm更改为mp4吗? (3认同)
  • 这是一个很棒的技巧。现在,我节省了很多代码,可以摆脱ffmpeg_asm.js。非常感谢你。 (2认同)
  • @John Doe 你说的是正确的。黑客可能会将类型更改为视频/mp4。这可以在任何浏览器中播放,包括 Safari 和 iOS。但这里的问题是视频容器仍然是 WEBM。这会导致在浏览器中播放视频时导引栏不起作用的问题。 (2认同)