gogoend / blog

blogs, ideas, etc.
MIT License
9 stars 2 forks source link

[译] 构建WebAssembly版本的FFmpeg——ffmpeg.wasm:第五部分:ffmpeg.wasm v0.3 —— pre-js 和 流媒体直播 #50

Closed gogoend closed 3 years ago

gogoend commented 4 years ago

原文:https://itnext.io/build-ffmpeg-webassembly-version-ffmpeg-js-part-5-ffmpeg-js-v0-3-pre-js-and-live-streaming-c1498939a74c 作者:Jerome Wu 翻译:gogoend

前一篇文章:[译] 构建WebAssembly版本的FFmpeg——ffmpeg.wasm:第四部分:ffmpeg.wasm v0.2 —— Web Worker 与 Libx264

在这一部分你将了解到:

  1. 使用--pre-js来重命名Module中的函数
  2. 将摄像头与ffmpeg.js一起使用

使用--pre-js来重命名Module中的函数

FFmpeg在运行时有一大堆输出,其中包含了一些重要的信息,比如视频的元信息、来自编/解码器的输出以及任务的进度。默认情况下,这些输出来自于原生C语言库的printf / sprintf。虽然你可以在开发者工具里看到这些输出,但你却无法使用JavaScript来进行操作。 幸运的是,在Emscripten中,我们能够通过--pre-js--post-js来重新定义一些默认函数的行为。在上述场景中,我们需要重新定义的函数是Module['printErr'](因为FFmpeg的输出使用stderr),并将其使用--pre-js来加入到我们的ffmpeg.js。

下面是我吸取的一些教训,供你参考:

这是目前在ffmpeg.js中所使用的prepend.js

事实上我们定义了一个新函数setLogger来注册我们的自定义输出函数,并重新定义了两个已存在的函数printprintErr。现在通过prepend.js,我们可以轻松地操作FFmpeg的输出信息,并开发更多功能(例如进度条)。

在构建脚本中加入--pre-js很容易(第54行):

现在在Module对象中已经有了setLogger,在初始化后我们就可以来使用它(第13行):

将摄像头与ffmpeg.js一起使用

此处我想要描述如何在实时流媒体中使用ffmpeg,在此我们以摄像头来作为示例。但大多数情况下,都具有相似的工作流程。

基本流程是:

  1. 使用MediaRecorder API来保存流到Blob
  2. 将Blob转换到Uint8Array数据
  3. 使用ffmpeg.js来对Uint8Array数据进行转码

第一步,我们使用getUserMedia来访问摄像头(必须使用https协议)

<video id="webcam" width="320px" height="180px"></video>
<script>
const webcam = document.getElementById('webcam');
(async () => {
  webcam.srcObject = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
  await webcam.play();
})();
</script>

第二步,使用MediaRecorder来记录片段

const startRecording = () => {
  const rec = new MediaRecorder(webcam.srcObject);
  const chunks = [];
  rec.ondataavailable = e => chunks.push(e.data);
  rec.onstop = async () => {
    transcode(new Uint8Array(await (new Blob(chunks)).arrayBuffer()));
  };
  rec.start();
};

第三步,重用前面章节的转码函数来进行转码 参见下方的CodePen来查看完整代码与实时Demo:

在第五部分中,我们学习了如何使用--pre-js来重新定义、扩展Module的能力,并介绍了如何在实时流媒体直播场景下使用ffmpeg。

在第六部分中,我们将会对文件系统进行深入的研究:构建WebAssembly版本的FFmpeg——ffmpeg.wasm:第六部分:深入研究文件系统

仓库:

ffmpeg-core.js: https://github.com/ffmpegwasm/FFmpeg ffmpeg.wasm: https://github.com/ffmpegwasm/ffmpeg.wasm