Closed gogoend closed 3 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
在这一部分你将了解到:
--pre-js
ffmpeg.js
FFmpeg在运行时有一大堆输出,其中包含了一些重要的信息,比如视频的元信息、来自编/解码器的输出以及任务的进度。默认情况下,这些输出来自于原生C语言库的printf / sprintf。虽然你可以在开发者工具里看到这些输出,但你却无法使用JavaScript来进行操作。 幸运的是,在Emscripten中,我们能够通过--pre-js或--post-js来重新定义一些默认函数的行为。在上述场景中,我们需要重新定义的函数是Module['printErr'](因为FFmpeg的输出使用stderr),并将其使用--pre-js来加入到我们的ffmpeg.js。
printf
sprintf
--post-js
Module['printErr']
stderr
下面是我吸取的一些教训,供你参考:
这是目前在ffmpeg.js中所使用的prepend.js:
prepend.js
事实上我们定义了一个新函数setLogger来注册我们的自定义输出函数,并重新定义了两个已存在的函数print和printErr。现在通过prepend.js,我们可以轻松地操作FFmpeg的输出信息,并开发更多功能(例如进度条)。
setLogger
print
printErr
在构建脚本中加入--pre-js很容易(第54行):
现在在Module对象中已经有了setLogger,在初始化后我们就可以来使用它(第13行):
此处我想要描述如何在实时流媒体中使用ffmpeg,在此我们以摄像头来作为示例。但大多数情况下,都具有相似的工作流程。
基本流程是:
第一步,我们使用getUserMedia来访问摄像头(必须使用https协议)
getUserMedia
<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来记录片段
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
前一篇文章:[译] 构建WebAssembly版本的FFmpeg——ffmpeg.wasm:第四部分:ffmpeg.wasm v0.2 —— Web Worker 与 Libx264
在这一部分你将了解到:
--pre-js
来重命名Module中的函数ffmpeg.js
一起使用使用
--pre-js
来重命名Module中的函数FFmpeg在运行时有一大堆输出,其中包含了一些重要的信息,比如视频的元信息、来自编/解码器的输出以及任务的进度。默认情况下,这些输出来自于原生C语言库的
printf
/sprintf
。虽然你可以在开发者工具里看到这些输出,但你却无法使用JavaScript来进行操作。 幸运的是,在Emscripten中,我们能够通过--pre-js
或--post-js
来重新定义一些默认函数的行为。在上述场景中,我们需要重新定义的函数是Module['printErr']
(因为FFmpeg的输出使用stderr
),并将其使用--pre-js
来加入到我们的ffmpeg.js。下面是我吸取的一些教训,供你参考:
--pre-js
使用ES5语法(没有箭头函数、const、let)这是目前在ffmpeg.js中所使用的
prepend.js
:事实上我们定义了一个新函数
setLogger
来注册我们的自定义输出函数,并重新定义了两个已存在的函数print
和printErr
。现在通过prepend.js,我们可以轻松地操作FFmpeg的输出信息,并开发更多功能(例如进度条)。在构建脚本中加入
--pre-js
很容易(第54行):现在在Module对象中已经有了
setLogger
,在初始化后我们就可以来使用它(第13行):将摄像头与
ffmpeg.js
一起使用此处我想要描述如何在实时流媒体中使用ffmpeg,在此我们以摄像头来作为示例。但大多数情况下,都具有相似的工作流程。
基本流程是:
第一步,我们使用
getUserMedia
来访问摄像头(必须使用https协议)第二步,使用
MediaRecorder
来记录片段第三步,重用前面章节的转码函数来进行转码 参见下方的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