最近遇到一个需求,需要实现多个.mp4格式视频的无缝连续播放。虽然现有开源播放器,可以基本实现需求,但为了足够轻还是自己用mse简单实现一下。此篇文章非常浅薄,仅作记录使用。
坑
💡 MSE 对视频格式有一定要求,需要是分段 MP4,笔者拿到的视频时未分段的mp4格式视频,使用ffmpeg进行分段。ffmpeg -i non_fragmented.mp4 -movflags frag_keyframe+empty_moov
因为对音视频格式知识的匮乏,这块卡了很长时间,详细可以查阅。
Transcoding assets for Media Source Extensions - Web APIs | MDN
实现
初始化
首先定义一个MediaSource对象,并赋值给video.src 。
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
let sourceBuffer;
添加sourceopen事件,该事件是在mediasource被video元素打开时触发。获取sourceBuffer对象,设置mode。
mediaSource.addEventListener("sourceopen", async () => {
console.log("source open!");
sourceBuffer = mediaSource.addSourceBuffer(mimeCodec)
sourceBuffer.mode ="sequence"
})
添加视频
通过fetch获取视频数据,并添加到sourcebuffer。
async function addVideo(fileUrl) {
try{
const res = await fetch(fileUrl)
const segment = await res.arrayBuffer();
sourceBuffer.appendBuffer(segment)
if(video.paused){
video.play();
}
}catch(err){
video.pause();
}
};
因为是本地运行,且视频较短,没有进行分段,如果视频较长,可以进行分段加载
const res = await fetch(fileUrl,{
headers:{
'range':'bytes=0-10240000'
},
})
总结
因为需求并不复杂,实现起来也比较简单。其实直接用到MSE的时候非常少,如果是常规的视频播放,使用现有的开源库即可。