JS编排视频
MediaSource
本质:
MediaSource
是一种可用于创建媒体流的对象,不过它的数据来源是JavaScript动态生成的,并非实时采集的。核心用途:主要用于实现流媒体播放,像视频点播、分段加载视频等场景都会用到它。
关键特性:
支持非实时的、可控的媒体播放。
可以把媒体数据分成多个
SourceBuffer
,从而实现分段加载和播放。能够进行随机访问,用户可以在视频的不同片段之间自由跳转。
视频处理
在官方文档中,MediaSource在创建addSourceBuffer时,需要传入MIME参数,他描述了视频的具体格式,且视频必须经历碎片化
处理后才能被使用,否则会触发报错。
碎片化处理
我们通过Bento4来处理视频,使用Bento4的mp4fragment工具,将视频文件碎片化。命令如下:
mp4fragment .\video\3.mp4 .\video\3-1.mp4
MEIE类型设置
addSourceBuffer所需要的MEIE类型不只是一个宽泛的类型,而是一个精确的类型,例如:video/mp4; codecs="avc1.640028, mp4a.40.2"
,他描述了视频的格式、视频编码、音频编码。
我们使用小工具来获取视频的详细编码格式:
is fragmented: true
字段标识该视频支持碎片化。
MediaSource.isTypeSupported('video/mp4; codecs="avc1.64001e, mp4a.40.2"'); // => true
表示视频的格式是video/mp4; codecs="avc1.64001e, mp4a.40.2“
,且该格式能被当前浏览器支持。
满足这两条要求的视频才能被使用。
使用示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<video id="videoBody" muted controls></video>
<script>
var video = document.getElementById('videoBody');
var assetURL = '/assets/1.mp4';
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
var isEnd = false
// 检查浏览器是否支持MediaSource
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
// 创建mediaSource
var mediaSource = new MediaSource;
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen () {
// 创建sourceBuffer
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
// 监听sourceBuffer的updateend事件
sourceBuffer.addEventListener('updateend', function (_) {
console.log('updateend');
// 检查mediaSource是否准备好
if (mediaSource.readyState === 'open' && !sourceBuffer.updating) {
// appendBuffer结束
if (isEnd) {
mediaSource.endOfStream();
video.play();
}
} else {
console.log('not ready');
}
});
// 添加视频
sourceBuffer.appendBuffer(buf);
// 模仿多个视频添加的情况
setTimeout(() => {
// 假设就是最后一个视频
isEnd = true
// 设置视频播放位置
sourceBuffer.timestampOffset = 60
// 添加视频
sourceBuffer.appendBuffer(buf);
}, 2000);
});
};
// 获取视频
function fetchAB (url, cb) {
var xhr = new XMLHttpRequest;
xhr.open('get', url);
// 以arraybuffer形式
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};
</script>
</body>
</html>
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果