背景
录制video/canvas上的视频然后下载到本地,但是遇到问题还是比较多的,进度条问题是最主要的一个。
录制代码
解决思路
因为是Matroska容器,在录制的时候少了一些媒体信息,所以播放器无法使用进度条。chrome官方不认为这是一个bug/issue.
额外
Matroska
基于EBML(Extensible Binary Meta Language 可扩展的二进制元语言),旨在成为多媒体格式容器的标准。 Matroska aims to become THE standard of multimedia container formats. It was derived from a project called MCF, but differentiates from it significantly because it is based on EBML (Extensible Binary Meta Language), a binary derivative of XML. EBML enables the Matroska Development Team to gain significant advantages in terms of future format extensibility, without breaking file support in old parsers.来自matroska官网。
支持的扩展名
目前Matroska支持5种扩展名的格式:mkv、mka、mk3d、mks、webm
- ffmpeg
ffmpeg.js也尝试了,但是问题比较多,因为使用了ffmpeg.wasm,其中SharedArrayBuffer在chrome默认中不支持。设置支持见
//ffmpge 命令确实好用呢
//但是在前端中性能不好以及一些API比较新有些浏览器不太支持
ffmpeg -i input_video.webm -c:v copy -c:a copy output_video.mp4
- 前端library
chatgpt有时候也害人啊,ts-embl库文件不全,好久没更新,解决出来还是有bug。于是找啊找,终于找到了。ebml.js
//使用的ebml.js
//mkv容器格式封装
const EBML=require ('./libs/EBML.js');
getSeekableBlob(inputBlob, cb) {
try{
if (typeof EBML === 'undefined') {
throw new BuildError('EBMLError', CONSTANT.EBML.LOAD_ERROR);
}
let reader = new EBML.Reader(),
decoder = new EBML.Decoder(),
tools = EBML.tools,
fileReader = new FileReader();
fileReader.onload = function(e) {
var ebmlElms = decoder.decode(this.result);
ebmlElms.forEach(function(element) {
reader.read(element);
});
reader.stop();
var refinedMetadataBuf = tools.makeMetadataSeekable(reader.metadatas, reader.duration, reader.cues);
var body = this.result.slice(reader.metadataSize);
var newBlob = new Blob([refinedMetadataBuf, body], {
type: 'video/webm'
});
cb(newBlob);
if(!newBlob||newBlob.size<1){
throw new BuildError('EBMLError', CONSTANT.EBML.TRANSFER_ERROR);
}
};
fileReader.readAsArrayBuffer(inputBlob);
}catch(error){
console.error(`[${error.type}]>${error.code}>${error}`);
}
}
// 处理过后的blob是带有duration的流
小结
前端处理不同的容器格式需要扎实的基础以及对容器格式的熟悉。比如flv.js 各种.wasm 等等。