如何使用ts-ebml库使Puppeteer录制的WebM文件支持Seekable?
解决Puppeteer录制的WebM视频无法拖拽播放(Seekable)的问题
问题描述
我正在开发一个使用Puppeteer和puppeteer-tab-recorder录制Chrome标签页并保存视频的程序,目前仅支持保存为.webm格式,但生成的文件无法拖拽播放(Seekable)。我找到ts-ebml库,官方说明其可实现该功能,但该库发布于6年前,缺乏可用的使用示例与完善文档。我尝试编写了如下代码:
function segmentWebM(inputPath, outputPath) { const fileBuffer = fs.readFileSync(inputPath); // Load the WebM file const decoder = new ebml.Decoder(); decoder.write(fileBuffer); decoder.end(); const tree = ebml.tools.makeMetadataSeekable(decoder.metadatas); const seekableWebMBuffer = Buffer.from( ebml.tools.makeMetadataSeekable(tree, true) ); fs.writeFileSync(outputPath, seekableWebMBuffer); }
但运行时提示decoder不存在write方法,仅能使用decode方法,其他方法均为私有。
解决方案:正确使用ts-ebml修复WebM可拖拽性
ts-ebml的Decoder类仅公开decode方法用于解析文件数据,你之前的代码误用了未公开的内部方法。以下是修正后的完整实现:
const fs = require('fs'); const ebml = require('ts-ebml'); function makeWebMSeekable(inputPath, outputPath) { // 读取原始WebM文件缓冲区 const fileBuffer = fs.readFileSync(inputPath); // 解码EBML元素 const decoder = new ebml.Decoder(); const ebmlElements = decoder.decode(fileBuffer); // 分离元数据和视频簇数据 const { metadata, clusters } = ebml.tools.metadata(ebmlElements); // 生成包含SeekHead的可拖拽元数据 const seekableMetadata = ebml.tools.makeMetadataSeekable(metadata, clusters); // 编码修正后的元数据 const encoder = new ebml.Encoder(); const encodedSeekableMetadata = encoder.encode(seekableMetadata); // 拼接元数据和原始簇数据,生成完整的可拖拽WebM文件 const outputChunks = [Buffer.from(encodedSeekableMetadata)]; clusters.forEach(cluster => outputChunks.push(Buffer.from(cluster.data))); const outputBuffer = Buffer.concat(outputChunks); // 写入输出文件 fs.writeFileSync(outputPath, outputBuffer); }
关键说明
- 解码流程:使用
decoder.decode()直接解析文件缓冲区,获取所有EBML结构元素 - 数据分离:通过
ebml.tools.metadata()将元数据和视频帧所在的簇(clusters)分开处理 - 生成可拖拽元数据:
makeMetadataSeekable会添加SeekHead节点,让播放器能定位视频时间轴 - 重新组装文件:将修正后的元数据重新编码后,和原始簇数据拼接,保证视频内容不变的同时修复可拖拽性
内容的提问来源于stack exchange,提问作者EgenSolve
相关产品推荐
相关产品推荐

