高级用法

本文档涵盖 ffmpeg.wasm 的高级实现模式和优化技术,重点介绍资源管理、元数据提取和文件系统策略。

执行控制与取消

管理长时间运行的 WebAssembly 任务对于浏览器稳定性至关重要。ffmpeg.wasm 提供了两种主要的任务终止方法。

超时与 AbortController

exec() 方法支持将超时(以毫秒为单位)作为第二个参数,并在第三个参数的对象中传入 AbortSignal。

  • 超时:如果进程超过特定持续时间,则自动杀死该进程。
  • AbortController:允许应用程序通过编程方式取消操作(例如,如果用户导航离开)。
const controller = new AbortController();
const { signal } = controller;
 
try {
 // 执行带有 10 秒超时和 AbortSignal 的任务
 await ffmpeg.exec(['-i', 'input.mp4', 'output.avi'], 10000, { signal });
} catch (err) {
 if (err.name === 'AbortError') {
 console.log('任务已被用户取消');
 }
}
 
// 手动取消:
controller.abort();

数据流:执行与中断

下图展示了 FFmpeg 类 API 到内部 FFMessageType 协议及 Worker 生命周期的连接。

高级用法

使用 ffprobe 提取元数据

ffmpeg.wasm 包含 ffprobe 功能,可在不进行完整转码的情况下提取媒体元数据。此功能通过 ffprobe() 方法暴露,该方法使用 FFMessageType.FFPROBE 消息类型。

// 将元数据提取到 JSON 文件
await ffmpeg.ffprobe(['-i', 'input.mp4', '-print_format', 'json', '-show_format', '-show_streams', '-o', 'metadata.json']);
const data = await ffmpeg.readFile('metadata.json');
const metadata = JSON.parse(new TextDecoder().decode(data));

来源:(由类结构隐含)

高级文件系统 (VFS) 策略

基于 Emscripten 的虚拟文件系统是浏览器内存与 WASM 核心之间的桥梁。

针对大文件的 WORKERFS

对于超过几百兆字节的文件,使用 writeFile(它将数据复制到 MEMFS)可能导致浏览器标签页因内存耗尽而崩溃。WORKERFS 允许直接将主机环境中的 File 或 Blob 对象挂载到文件系统中,而无需将它们复制到 WASM 堆中。

  • 限制:WORKERFS 是只读的。
  • 限制:由于 Emscripten 工具链中的 32 位指针,大多数浏览器中的 WebAssembly 目前限制为 2 GB 文件大小。
// 通过 WORKERFS 挂载本地大文件
await ffmpeg.mount('WORKERFS', {
 files: [fileObject], // 浏览器 File 或 Blob
}, '/mnt');
 
await ffmpeg.exec(['-i', '/mnt/large_video.mp4', 'output.mp4']);
await ffmpeg.unmount('/mnt');

VFS 实体关系图

此图映射了 JavaScript VFS 方法到内部 Emscripten FS 操作。

高级用法

性能与优化

自定义核心构建

默认的 @ffmpeg/core 包含广泛的库(x264, x265, libvpx 等),导致二进制文件大小约为 30MB。对于具有特定需求的生产应用(例如仅进行 MP3 到 WAV 转换),建议构建自定义核心以减少加载时间。

  • 二进制大小:在 Makefile 中减少启用的解码器/编码器可以显著缩小 WASM 文件。
  • SIMD:在 Docker 构建过程中启用 SIMD 可以提高性能,但这需要兼容的浏览器。

对比:原生 vs. WASM

由于 WASM 运行时开销和缺乏硬件加速,浏览器中的性能显著低于原生执行。

任务原生 FFmpegcore (单线程)core-mt (多线程)
WebM 转 MP4~5.2 秒~128.8 秒 (0.04x)~60.4 秒 (0.08x)

约束总结

约束限制 / 详情
最大文件大小2 GB(Emscripten/WASM 32 位限制)
内存取决于浏览器的 SharedArrayBuffer 和 WASM 堆限制
IO建议使用 WORKERFS 处理大输入以避免 OOM(内存溢出)
CORS需要使用 toBlobURL 或本地托管来加载核心资源