先祭出Github:github.com/qiaozi-tech…
0.背景
国内的各个浏览器厂商对于Video都有着各种技术上的限制和管控,例如腾讯系的X5引擎对Video进行了大量的魔改,其中包括:
- 所谓的同层播放层(??)
- 无法正常playsinline
- 即使静音也无法自动播放
- 各种播放前后的广告
- 纯Native组件,无法很好的进行触摸事件交互
当然,其他厂商例如百度/UC/360及手机厂商的默认系统浏览器也做了非常多恶心人的奇怪限制。
1.示例
qiaozi-tech.github.io/WXInlinePla… (视频25M左右,耐心等待加载一下,毕竟需要FQ)
2.兼容性
在BrowserStack中测试,主流系统版本均通过,其余机型请考虑通过降级页面功能进行处理:
- iOS 9+ (含Safari及Safari WebView)
- Android 5+(部分4.4.2+的系统浏览器也支持)
- IE11+
- Chrome 24+
- Firefox
- Safari
- Edge 15+
3.优点
- 整体核心极小(gzip ~110kb),减少移动端加载与解析时间
- 性能进行高度优化,稳定使用在线上产品好惠买中
- 移动端兼容性良好,不依赖系统/软件平台的【魔改】播放器,便于产品实现
4.限制
目前仅支持FLV(AVC+AAC+baseline)格式,如果是MP4等其他格式请使用ffmpeg进行转码
ffmpeg -i <your file> -vcodec h264 -acodec aac -profile:v baseline mtv.flv
5. 起步
<html>
<head></head>
<body>
<div id="container"></div>
<script src="./dist/index.js"></script>
<script>
// 相关特性不支持时需要降级页面功能
if(WXInlinePlayer && WXInlinePlayer.isSupport()){
WXInlinePlayer.init({
asmUrl: './dist/TinyH264.asm.js',
wasmUrl: './dist/TinyH264.wasm.js',
}).catch(()=>{
// 部分浏览器会在解析wasm/asm时失败(但相关特性支持)
// 此时同样需要降级页面功能
});
WXInlinePlayer.ready().then(()=>{
let player = new WXInlinePlayer({
url: './sample.flv', // 仅支持flv格式(H264+AAC)
$container: document.getElementById('container'),
volume: 1.0, // iOS不允许代码调节声量,请注意兼容
muted: false, // iOS和Android均支持代码控制静音
autoplay: false,
loop: false
});
player.on('load:success', ()=>{
player.play();
});
player.on('load:error', ()=>{
console.log('>>>>>>>>>load error');
});
player.on('play', ()=>{
player.volume(0.0); // GET/SET方法
player.mute(true); // GET/SET方法
player.resume();
player.pause();
player.stop();
});
player.on('stop', ()=>{
player.destroy();
player = null;
});
// iOS及Chrome高版本禁止声音播放
// WXInlinePlayer的音画同步依靠音源的播放时间戳进行对齐
// 当音源播放被阻止时会等待250ms后尝试直接绘制画面
// 同时触发playtimeout
player.on('playtimeout', ()=>{
console.log('>>>>>>>>>playtimeout');
});
});
}
</script>
</body>
</html>
6.TODO
- 流式解析,提高首帧显示和内存占用情况
- 支持FLV直播流播放
- 进一步提升H264解析性能
7. 其余问题
- 如何获取播放器的当前进度?
由于需要考虑到playtimeout的问题,因此API不提供相关的支持。一个简单粗暴的办法是使用setTimeout自己粗略模拟。当然如果仍然想获取相关的数据,可以使用 player.sound.seek() 方法来获取,但请做好返回类型的判断(playtimeout使用此API会返回非Number类型数据)。
- 为什么在部分低端机器上有音画不同步的情况
WXInlinePlayer的音画同步依靠音频时间戳,浏览器目前没有非常底层的方式控制音频buffer,同时由于此实现是CPU软解H264,低端机CPU性能羸弱,解析一帧H264的时间会比较长(大约30-50ms),而音频大部分是24ms左右,因此很容易出现音画不同步的情况。你可以尝试降低视频码率试一试是否有缓解。