WXInlinePlayer
0.背景
国内的各个浏览器厂商对于Video都有着各种技术上的限制和管控,例如腾讯系的X5引擎对Video进行了大量的魔改,其中包括:
- 所谓的同层播放层
- 无法正常playsinline
- 即使静音也无法自动播放
- 各种播放前后的广告
- 纯Native组件,无法很好的进行触摸事件交互
1.示例(720P视频,文件较大请耐心等待)
https://qiaozi-tech.github.io/WXInlinePlayer/example/index.html
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 -vf scale=640:-1 mtv.flv
- 1080P视频软解效率不高,会出现卡顿的情况,推荐增加转码参数:
- 分辨率: -vf scale=-1:360
- fps: -r 25
- 码率:-b:v 1200K
5. 起步
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>WXInlinePlayer Demo Page</title>
<style>
* {
margin: 0;
padding: 0;
}
#container {
width: 1280px;
height: 720px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -640px;
margin-top: -360px;
}
</style>
</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"
});
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-demux替换为wasm实现,整合demux + h264codec,大幅度降低内存使用
- 流式解析,提高首帧显示和内存占用情况
- 进一步提升H264解析性能
- 支持FLV直播流播放
- 多worker线程解码支持
7. 其余问题
- 如何获取播放器的当前进度?
由于需要考虑到playtimeout的问题,因此API不提供相关的支持。一个简单粗暴的办法是使用setTimeout自己粗略模拟。当然如果仍然想获取相关的数据,可以使用 player.sound.seek() 方法来获取,但请做好返回类型的判断(playtimeout使用此API会返回非Number类型数据)。
- 为什么在部分低端机器上有音画不同步的情况
WXInlinePlayer的音画同步依靠音频时间戳,浏览器目前没有非常底层的方式控制音频buffer,同时由于此实现是CPU软解H264,低端机CPU性能羸弱,解析一帧H264的时间会比较长(大约30-50ms),而音频大部分是24ms左右,因此很容易出现音画不同步的情况。你可以尝试降低视频码率试一试是否有缓解。(目前已进行强制追帧,低端机画面可能会有跳跃,但如果失败仍然会有不同步情况)