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

13

我正在尝试使用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();

这段代码按预期工作并返回一个webm视频

var blob = new Blob(recordedBlobs, {type: 'video/webm'});

现在我想要一个mp4文件,并检查muaz-khan的ffmpeg.js。示例仅显示如何在具有2个单独流(音频和视频)时转换为mp4。但我有一个带有附加音轨的流。我能将这样的流转换为mp4吗?应该如何完成?

1个回答

17

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

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

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

在浏览器内部进行视频转码并不建议,因为这将消耗更多的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"

所以你可以通过以下技巧直接从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

3
这是一个很棒的技巧。现在我可以省下许多代码,并且可以摆脱 ffmpeg_asm.js。非常感谢您。 - q-jack
@Ajay "所以你可以通过以下hack直接从Chrome MediaRecorder获取mp4录制" $ ffmpeg -i file.mp3 输出 Input #0, matroska,webm, from 'file.mp3': Metadata: encoder : Chrome Duration: N/A, start: 0.000000, bitrate: N/A Stream #0:0(eng): Audio: opus, 48000 Hz, mono, fltp (default) 而使用 .wav 文件输入的方法则需要 $ ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 file.mp3 输出 opus - guest271314
6
“@Ajay what do you mean by "get mp4 recording directly"? Maybe i made some mistake, but in my test i only get the original webm/h264 video but with a different mime type. So the video container doesnt change. Thus the binary data is exactly the same after the new Blob(...) line, right? Thats what i tried: https://jsfiddle.net/zqd8qf6e/ Isn't the goal here that the video container changes from webm to mp4 without ffmpeg.js?”“@Ajay你所说的“直接获取mp4录制”是什么意思?也许我犯了一些错误,但在我的测试中,我只得到了原始的webm / h264视频,但MIME类型不同。因此,视频容器并没有改变。因此,在new Blob(...)行之后,二进制数据完全相同,对吗?这就是我尝试过的内容:https:// jsfiddle.net / zqd8qf6e / 难道这里的目标不是在没有使用ffmpeg.js的情况下将视频容器从webm更改为mp4吗?” - John Doe
2
@John Doe,你说的是正确的。这个hack可能会将类型更改为video/mp4。这将在任何浏览器中播放,包括Safari和iOS。但问题在于视频容器仍然是WEBM。这导致在浏览器中播放视频时,搜索栏无法正常工作。 - NME New Media Entertainment
对我来说,设置var options = {mimeType: 'video/webm;codecs=h264'}记录video/x-matroska;codecs=avc1的视频,但这个“hack”不起作用 :( - undefined
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接