ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

@remotion/webcodecs:基于 WebCodecs 在浏览器中完成视频/音频转换的 Remotion 包

@remotion/webcodecs:基于 WebCodecs 在浏览器中完成视频/音频转换的 Remotion 包 remotion/webcodecs基于 WebCodecs 在浏览器中完成视频/音频转换的 Remotion 包【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotionremotion/webcodecs是 Remotion 单仓monorepo中负责浏览器端媒体转换的包它借助remotion/media-parser解析输入的音视频数据再利用浏览器的 WebCodecs API 完成解码与编码最终在浏览器内输出新的 MP4 / WebM / WAV 文件。阅读本文后你将掌握该包的安装与版本约束、convertMedia()的完整参数与返回值、extractFrames()抽帧接口以及从源码层面理解其解析 → 解码 → 重编码 → 容器封装的实现链路和测试组织方式。状态提示官方文档中明确标注 Remotion WebCodecs 正在逐步转向 Mediabunny见 webcodecs 文档入口 顶部的警示且该包标注为不稳定 APIUnstable生产使用前需留意版本变更风险。该功能自 v4.0.229 起可用。包定位与安装方式包的元信息来自 package.json包名remotion/webcodecs当前仓库版本4.0.521描述为 Media conversion in the browser运行时唯一依赖是remotion/media-parserworkspace 依赖说明媒体解析能力完全复用 media-parser 包除主入口外还提供三个子路径导出./web-fs基于 File System Access API 的写盘 Writer、./buffer写入可扩容内存 ArrayBuffer 的 Writer和./workerWorker 入口构建产物同时发布 CommonJSdist/index.js与 ESMdist/esm/index.mjs两套入口。README 给出的安装命令要求使用精确版本npm install remotion/webcodecs --save-exact并特别强调所有remotion与remotion/*包的版本必须保持完全一致即要移除版本号前的^字符。这是 Remotion 全家桶的一致约束混用不同版本的子包会触发ensure-correct-version一类的版本检查失败。能做什么结合 README 的概述与 webcodecs 文档索引在实现了 WebCodecs 的浏览器中该包可以在多种格式之间转换视频输入.mp4、.mov、.m4a、.mkv、.webm、.avi、.ts、.m3u8、.wav、.mp3、.flac、.aac输出MP4、WebM、WAV旋转视频修正错误的画面方向高效地从视频中抽取指定时间戳的帧extractFrames()从视频中提取音频逐帧操作视频像素通过onVideoFrame回调返回修改后的VideoFrame;修复MediaRecorder录制的视频缺少时长信息、Seek 性能差的问题。官方文档同时强调性能特点与 WebAssembly 方案不同WebCodecs 拥有 GPU 加速通道因此处理速度通常显著快于在线转换器或 WASM 编解码方案。核心入口 convertMedia()convertMedia()是本包的主 API源码位于 convert-media.ts。其调用流程是校验参数container必须是getAvailableContainers()返回的合法值videoCodec必须属于availableVideoCodecs否则直接 reject 一个TypeError见 convert-media.ts#L160-L174通过autoSelectWriter()选择输出 Writer默认内存 buffer也可传入webFsWriter/bufferWriter用MediaParserInternals.internalParseMedia()驱动 media-parser 解析src并注入自制的onVideoTrack/onAudioTrack处理函数把解码出的帧送进 WebCodecs 编码器通过throttledStateUpdate做进度节流默认每 100ms 触发一次onProgress解析完成后state.waitForFinish()等待 muxer 落盘最终返回{save, remove, finalState}。基本用法以下示例继承自 convert-a-video 文档。从 URL 转换需要源站开启 CORSimport {convertMedia} from remotion/webcodecs; const result await convertMedia({ src: https://remotion.media/BigBuckBunny.mp4, container: webm, }); const blob await result.save();从input typefile拿到的File对象转换import {convertMedia} from remotion/webcodecs; // Get an actual file from an input typefile element const file new File([], video.mp4); const result await convertMedia({ src: file, container: webm, }); const blob await result.save();指定输出编码例如 WebM VP9 Opusimport {convertMedia} from remotion/webcodecs; const result await convertMedia({ src: https://remotion.media/BigBuckBunny.mp4, container: webm, videoCodec: vp9, audioCodec: opus, }); const blob await result.save();输入/输出格式与编码支持根据 convert-a-video 文档 与 convertMedia 参考类别支持值输入容器ISO Base Media.mp4/.mov/.m4a、Matroska.mkv/.webm、.avi、MPEG-TS.ts、HLS.m3u8、.wav、.mp3、.flac、.aac输出容器mp4、webm、wav输出视频编码VP8仅 WebM、VP9仅 WebM、H.264仅 MP4videoCodec参数的类型联合中另含h265以 convert-media.mdx 的参数说明为准输出音频编码OpusWebM、AACMP4、PCMWAVconvertMedia()参数层面以getDefaultAudioCodec()决定默认值完整参数说明convertMedia()的参数签名很长完整定义见 convert-media.ts#L132-L154。结合 convert-media.mdx 的参数文档常用参数如下参数类型说明srcstring | File | Blob | 本地路径媒体来源传入本地文件路径时只能 copy 轨道且必须把reader设为nodeReadercontainerConvertMediaContainer必填。输出容器当前支持mp4、webm、wavvideoCodec?ConvertMediaVideoCodec视频编码默认由getDefaultVideoCodec()按容器决定提供onVideoTrack时会被其覆盖audioCodec?ConvertMediaAudioCodec音频编码默认由getDefaultAudioCodec()决定提供onAudioTrack时会被其覆盖controller?WebCodecsController由webcodecsController()创建用于暂停 / 恢复 / 中止转换reader?media-parser reader默认webReader支持 URL 与FileexpectedDurationInSeconds?number | null预知输出时长用于估算 MP4 元数据区大小不传时默认分配 2MB超过约 1 小时的长视频若超出可能导致最终写入失败expectedFrameRate?number | null预知输出帧率同样用于 MP4 元数据区估算不传时使用保守回退值 60rotate?number旋转角度度resize?ResizeOperation缩放操作见ResizeOperation类型logLevel?MediaParserLogLevelerror/warn/info/debug/trace默认infoprogressIntervalInMs?numberonProgress触发节流间隔源码默认 100msonProgress?(state: ConvertMediaProgress) void进度回调onVideoFrame?ConvertMediaOnVideoFrame逐帧钩子见下文onAudioData?ConvertMediaOnAudioData逐段音频钩子onVideoTrack?/onAudioTrack?轨道处理函数高级轨道变换对每条轨道决定 copy / re-encode / 丢弃fields?、seekingHints?、selectM3uStream?等—继承 media-parser 的解析字段查询与 HLS 流选择参数onProgress收到的ConvertMediaProgress状态定义在 convert-media.ts#L51-L60export type ConvertMediaProgress { decodedVideoFrames: number; decodedAudioFrames: number; encodedVideoFrames: number; encodedAudioFrames: number; bytesWritten: number; millisecondsWritten: number; expectedOutputDurationInMs: number | null; overallProgress: number | null; };onVideoFrame是像素级处理的关键钩子回调收到{frame, track}可同步或异步返回同一个或替换后的VideoFrame返回值即被送入编码器函数返回后convertMedia()会负责对输入和输出帧调用.close()释放资源见 convert-media.mdx 的说明。返回值与结果处理convertMedia()返回的ConvertMediaResult定义见 convert-media.ts#L62-L66包含save(): PromiseBlob把转换结果取回为Blob可用于下载、上传、video播放或存入 IndexedDBremove(): Promisevoid清理转换过程中创建的临时资源finalState: ConvertMediaProgress转换结束时的最终统计状态。文档给出的三类典型消费方式下载、上传、展示示例// 下载 const blob await result.save(); const url URL.createObjectURL(blob); const link document.createElement(a); link.href url; link.download converted-video.webm; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url);// 上传 const blob await result.save(); const formData new FormData(); formData.append(video, blob, converted-video.webm); await fetch(/api/upload, {method: POST, body: formData});// 在 video 中展示 const blob await result.save(); const url URL.createObjectURL(blob); const video document.createElement(video); video.src url; video.controls true; document.body.appendChild(video); // 用完记得 URL.revokeObjectURL(url)此外需要注意错误路径controller.abort()会触发MediaParserAbortError(Conversion aborted by user)使 Promise reject见 convert-media.ts#L179-L196解码失败时抛出AudioUndecodableError/VideoUndecodableError在 index.ts 中导出。抽帧 API extractFrames()除了整体转封装/重编码extract-frames.ts 提供了按时间戳抽帧的轻量接口参数定义非常精简export type ExtractFramesProps { src: string; timestampsInSeconds: number[] | ExtractFramesTimestampsInSecondsFn; onFrame: (frame: VideoFrame) void; signal?: AbortSignal; acknowledgeRemotionLicense?: boolean; logLevel?: MediaParserLogLevel; };即传入媒体 URL、时间戳数组或生成时间戳的函数每解码出一帧就通过onFrame回调交给调用方支持AbortSignal中止。源码中它内部委托给internalExtractFrames()并注入parseMedia实现仓库还附带了 Web Worker 版本入口extractFramesOnWebWorker./worker子路径导出便于把解码放到独立线程。对应的文档见 extract-frames.mdx。配套 API 一览index.ts 导出的完整公开面可分为几组能力探测getAvailableContainers()、getAvailableVideoCodecs(container)、getAvailableAudioCodecs(container)、getDefaultVideoCodec()、getDefaultAudioCodec()canCopyVideoTrack()/canCopyAudioTrack()判断轨道能否免重编码直接拷贝canReencodeVideoTrack()/canReencodeAudioTrack()判断当前浏览器能否重编码默认轨道处理defaultOnVideoTrackHandler()/defaultOnAudioTrackHandler()给出能 copy 就 copy否则 re-encode的默认策略可在自定义onVideoTrack/onAudioTrack中复用或修改其决策详见 track-transformation 文档编解码器工厂createVideoDecoder()、createAudioDecoder()、createVideoEncoder/createAudioEncoder内部实现封装了浏览器差异处理像素/采样率工具convertAudioData()改变AudioData的格式或采样率、getPartialAudioData()提取指定时间窗的音频数据、rotateAndResizeVideoFrame()旋转 缩放单个VideoFrame控制器webcodecsController()创建支持 pause / resume / abort 的控制器对象文档见 webcodecs-controller.mdx、pause-resume-abort 文档。容器封装层自己实现的 MP4 / Matroska / WAV 写入器从源码结构看写出容器这一步完全没有依赖 FFmpeg 或第三方 muxer而是用 TypeScript 手写了三类封装器的 box/element 序列化逻辑位于 src/create/ 目录ISO Base MediaMP4/MOV/M4Acreate-iso-base-media.ts 之下是完整的 box 树——moov含mvhd、trak/tkhd、mdia/mdhd、stbl表族stts、stss、ctts、stsc、stsz、stco、stsd中的avc1/avcc/hvc1/mp4a具体编码描述以及ftyp、colr颜色空间、udta/metahdlr等Matroska/WebMcreate-matroska-media.ts 及配套的cluster、matroska-cuesSeek 索引、matroska-trackentry、matroska-segment等文件解释了为什么输出的 WebM 有 cues 从而 Seek 性能好WAVcreate-wav.ts 实现 PCM 音频的 RIFF 头写入。字节落盘则由 writers/ 目录下的 Writer 抽象负责buffer-implementation/writer.ts提供内存实现web-fs.ts基于 File System Access API 直接写浏览器文件系统auto-select-writer.ts 在用户未显式传writer时自动选择默认内存 buffer这也是为什么save()能拿到整个Blob。这套设计也与package.json中./buffer、./web-fs、./worker三个子路径导出对应。测试体系包内有两层测试脚本见 package.json单元/字节级测试bun test src/test。src/test/ 目录对 MP4 box 序列化做了逐字节的回归验证如 create-ftyp.test.ts、stbl.test.ts、mp4-header-length.test.ts、colr.test.ts以及跨格式 remux 集成测试 remux-serverside.test.ts浏览器端集成测试playwright test src/it-testsplaywright.config.tssrc/it-tests/ 覆盖真实转封装链路format-conversion.ts、抽帧精度extract-frames-accuracy.test.mts、边缘用例edge-cases.ts与音频重采样resample-audiodata.test.ts。这也印证了输入解析靠 media-parser、编解码靠 WebCodecs、封装自研的三层结构。许可与稳定性该包采用 Remotion Licensepackage.json 中 license 字段指向官方许可条款商业使用需遵循 Remotion 的许可体系官方文档在每页顶部都标注了 Unstable API 警告与We are phasing out Remotion WebCodecs and are moving to Mediabunny的过渡提示意味着 API 仍可能变化且长期方向是迁移到 Mediabunny依赖 WebCodecs 浏览器 API运行环境必须是实现了 WebCodecs 的现代浏览器或具备对应 polyfill/兼容层的环境本地文件路径读取场景则需配合 media-parser 的nodeReader。小结remotion/webcodecs把浏览器内转码做成了一套可组合的 APIconvertMedia()负责端到端转换并暴露进度、逐帧钩子与轨道级控制extractFrames()、getPartialAudioData()、convertAudioData()覆盖抽帧与音频处理底层则由自研的 MP4/Matroska/WAV 写入器与remotion/media-parser的解析能力支撑。使用时记住三件事所有 Remotion 包版本严格对齐--save-exact、container与videoCodec/audioCodec的容器-编码配对约束VP8/VP9 配 WebMH.264/AAC 配 MP4、以及save()/remove()的显式资源管理同时关注官方向 Mediabunny 迁移的进度。【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表