交互式沙盒

交互式沙盒是一个基于 Web 的环境,允许用户直接在浏览器中实验 ffmpeg.wasm,无需任何安装或开发配置。本文档解释了沙盒的工作原理、其内部状态管理、组件生命周期以及它如何与虚拟文件系统 (VFS) 交互。

目的与概述

沙盒作为 @ffmpeg/ffmpeg API 的实时演示,专门展示资源加载、命令执行和文件系统管理功能。

交互式沙箱

架构与状态管理

沙盒是使用 Material UI 实现的 React 应用程序。Playground 根组件管理 FFmpeg 实例的高级状态,而 Workspace 则处理用户交互。

组件层次结构

  • Playground:管理 FFmpeg 实例和加载状态的主容器
  • CoreSwitcher:用于在单线程 (ST) 和多线程 (MT) 核心之间切换的用户界面
  • CoreDownloader:使用 LinearProgressWithLabel 显示资源获取进度
  • Workspace:包含文件管理器和命令编辑器的活动区域

State 枚举

沙盒通过三个主要状态转换来管理 WebAssembly 二进制文件的异步加载:

  1. NOT_LOADED:初始状态。
  2. LOADING:正在通过 toBlobURL 获取资源。
  3. LOADED:ffmpeg.load() 已解析,且 Workspace 可见。

核心加载逻辑

Playground 中的 load 函数负责获取 .js、.wasm 和(可选).worker.js 文件。它使用来自 @ffmpeg/util 的 toBlobURL 来跟踪下载进度。

交互式沙箱

函数文件:行号描述
toBlobURL获取资源并返回 Blob URL,向 setProgress 报告进度。
ffmpeg.load使用提供的 Blob URL 初始化 WebAssembly 模块。
ffmpeg.terminate在重新加载之前调用,以清理现有工作进程/内存。

工作区组件

FileSystemManager

FileSystemManager 为基于 Emscripten 的虚拟文件系统提供用户界面。它将用户操作映射到 FFmpeg 类方法:

  • 上传:使用 ffmpeg.writeFile
  • 下载:使用 ffmpeg.readFile 后跟 downloadFile 工具
  • 导航:使用 ffmpeg.listDir 填充 nodes 状态
  • 操作:支持 createDir、deleteFile 和 rename

命令编辑器

Editor 组件使用 react-ace 允许用户将 FFmpeg 命令输入为 JSON 数组。

  • 执行:Workspace 中的 onExec 函数解析 JSON 并调用 ffmpeg.exec(args)
  • 事件监听器:在执行前,它会附加 log 和 progress 事件的监听器以更新用户界面

多线程支持

CoreSwitcher 组件启用 ffmpeg.wasm 的多线程版本。

  • 要求:它检查 typeof SharedArrayBuffer !== "function",如果浏览器缺乏跨源隔离,则禁用切换
  • 切换:当切换时,它会触发使用 CORE_MT_URL 重新加载沙盒

工具函数

  • downloadFile:一个辅助函数,创建临时的 <a> 标签和 URL.createObjectURL 以触发浏览器下载处理后的缓冲区
  • fetchFile:用于将浏览器的 File 对象转换为 Uint8Array 以便写入 writeFile