☀ 业务需求:
直播过程中需要不断的拉流进行播放,遇到网络突然中断的情况时,直播推流中断会中断;此时因为播放器拉流失败无法正常播放而导致播放器会播放失败。当直播恢复推流恢复时候,播放器需要自动恢复拉流来自动恢复直播播放。综合了常用的播放器做对比,对比结果如下:
- 阿里云播放器(aliplayer)推流中断时播放失败,此时其可以设置指定重复拉流次数的恢复拉流尝试,当达到尝试的次数时,播放器会报错,提示信息不是很明显,当再次恢复推流时候,会一直停留在播放失败的页面;
- 腾讯播放器(TcPlayerLite)推流失败时有指定的错误提示【 根据不同的错误码设置不同的错误提示】,方便用户知晓直播状态;当直播失败时可以在播放界面显示视频封面,相对来说比较美观;
- aliplayer不支持直播暂停,tcplayer支持直播暂停【因为当时Android手机的同层播放时,支持直播暂停,直播中断时,手机上会不断尝试拉流,直至正常播放】,因此为了达到与手机微信端一致的效果,就采取了此方案。
- aliplayer配置直播地址的参数是固定的【 source 】,直播地址没有要求;而tcplayer配置直播地址属性的参数是收到直播推流地址影响的【 m3u8、flv等】,同时可以配置多个推流地址,在手机端和PC端会自动切换【浏览器支持flash的话会自动匹配flv格式的直播】。
🌞 代码配置:
- 在 head 标签中引入播放器的cdn;
- 在页面创建播放器容器,样式自定义;
- 初始化视频直播播放器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<!-- TCPlayerLite 初始化cdn -->
<script src="https://imgcache.qq.com/open/qcloud/video/vcplayer/TcPlayer-2.3.3.js"></script>
<!-- or -->
<script src="https://cloudcache.tencent-cloud.com/open/qcloud/video/vcplayer/TcPlayer-2.3.3.js"></script>
</head>
<body>
<div id="app">
<!-- 初始化播放器 -->
<div id="tc_palyer_lite" style="width:100%; height:auto;"></div>
</div>
</body>
</html>
🛠 初始化直播播放器
- 设置直播拉流地址和视频播放器封面;
- 设置H5兼容(微信同层播放设置);
- 设置播放器错误码以及对应提示信息;
- 设置直播失败定时重连。
export default {
name: "TcPlayer",
data() {
return {
player: null,
videoUrl: "https://myun-hw-s3.myun.tv/e54ypd59/5z4op6m0/l7b9r8g0/0eyv9aal_1559181924071539192_origin.m3u8" /* 直播拉流地址 */,
poster: "" /* 视频封面 */
};
},
mounted() {
this.initPlayer();
},
methods: {
// 初始化播放器
initPlayer() {
if (this.player) {
this.player.destroy();
this.player = null;
}
let options = {
m3u8: this.videoUrl /* 播放地址 */,
// mp4: "" /* 回看地址 */,
// poster: this.poster /* 视频封面 */,
live: false /* 是否直播 */,
autoplay: true,
poster: { style: "cover", src: this.poster },
pausePosterEnabled: true /* 暂停时显示封面 默认为true */,
wording: {
1002: "即将直播,请稍等",
2032: "请求视频失败,请检查网络",
2048: "请求m3u8文件失败,可能是网络错误或者跨域问题"
},
controls: "system", //default||'' 显示默认控件,none 不显示控件,system 移动端显示系统控件
x5_player: true,
x5_type: "h5-page",
x5_fullscreen: true,
listener: function(msg) {
// 播放失败,重新连接
if (msg.type == "error") {
setTimeout(() => {
this.player.load(); // 重连
}, 4000);
}
}
};
// 初始化
this.player = new TcPlayer("tc_player_view", options);
}
}
};
🐱👓 参数列表:
参数 | 类型 | 默认值 | 参数说明 |
---|---|---|---|
m3u8 | String | 无 | 原画 M3U8 播放 URL。 |
m3u8_hd | String | 无 | 高清 M3U8 播放 URL。 |
m3u8_sd | String | 无 | 标清 M3U8 播放 URL。 |
flv | String | 无 | 原画 FLV 播放 URL。 |
flv_hd | String | 无 | 高清 FLV 播放 URL。 |
flv_sd | String | 无 | 标清 FLV 播放 URL。 |
mp4 | String | 无 | 原画 MP4 播放 URL。 |
mp4_hd | String | 无 | 高清 MP4 播放 URL。 |
mp4_sd | String | 无 | 标清 MP4 播放 URL。 |
rtmp | String | 无 | 原画 RTMP 播放 URL。 示例:rtmp://xxxxxxxxxxxxxxx_ |
rtmp_hd | String | 无 | 高清 RTMP 播放 URL。 示例:rtmp://xxxxxxxxxxxxxxxx_hd |
rtmp_sd | String | 无 | 标清 RTMP 播放 URL。 示例:rtmp://xxxxxxxxxxxxxxxxx_sd |
width | Number | 无 | 必选,设置播放器宽度,单位为像素。 示例:640 |
height | Number | 无 | 必选,设置播放器高度,单位为像素。 示例:480 |
volume | Number | 0.5 | 设置初始音量,范围:0到1 [v2.2.0+]。 示例:0.6 |
live | Boolean | false | 必选,设置视频是否为直播类型,将决定是否渲染时间轴等控件,以及区分点直播的处理逻辑。 |
autoplay | Boolean | false | 是否自动播放。(备注:该选项只对大部分 PC 平台生效) |
poster | String / Object | 无 | 预览封面,可以传入一个图片地址或者一个包含图片地址 src 和显示样式 style 的对象。- default 居中1:1显示;- stretch 拉伸铺满播放器区域,图片可能会变形;- cover 优先横向等比拉伸铺满播放器区域,图片某些部分可能无法显示在区域内。 示例: "xxxxxxxxx.jpg " 或者{"style": "cover", "src": xxxxxxx.jpg } [v2.3.0+] |
controls | String | "default","system" | default 显示默认控件,none 不显示控件,system 移动端显示系统控件。(备注:如果需要在移动端使用系统全屏,就需要设置为 system。默认全屏方案是使用 Fullscreen API + 伪全屏的方式,在线示例) |
systemFullscreen | Boolean | false | 开启后,在不支持 Fullscreen API 的浏览器环境下,尝试使用浏览器提供的 webkitEnterFullScreen 方法进行全屏,如果支持,将进入系统全屏,控件为系统控件。 |
flash | Boolean | true | 是否优先使用 Flash 播放视频。(备注:该选项只对 PC 平台生效[v2.2.0+]) |
flashUrl | String | 无 | 可以设置 flash swf url。 (备注:该选项只对 PC 平台生效 [v2.2.1+]) |
h5_flv | Boolean | false | 是否启用 flv.js 的播放 flv。启用时播放器将在支持 MSE 的浏览器下,采用 flv.js 播放 flv,然而并不是所有支持 MSE 的浏览器都可以使用 flv.js,所以播放器不会默认开启这个属性,[v2.2.0+]。 |
x5_player | Boolean | false | 是否启用 TBS 的播放 flv 或 hls 。启用时播放器将在 TBS 模式下(例如 Android 的微信、QQ 浏览器),将 flv 或 hls 播放地址直接赋给 <video> 播放。 |
x5_type | String | 无 | 通过 video 属性 “x5-video-player-type” 声明启用同层 H5 播放器,支持的值:h5-page (该属性为 TBS 内核实验性属性,非 TBS 内核不支持);示例:"h5-page" |
x5_fullscreen | String | 无 | 通过 video 属性 “x5-video-player-fullscreen” 声明视频播放时是否进入到 TBS 的全屏模式,支持的值:true (该属性为 TBS 内核实验性属性,非 TBS 内核不支持) 。 示例:"true" |
x5_orientation | Number | 无 | 通过 video 属性 “x5-video-orientation” 声明 TBS 播放器支持的方向,可选值:0(landscape 横屏),1:(portraint竖屏),2:(landscape | portrait 跟随手机自动旋转)。 (该属性为 TBS 内核实验性属性,非 TBS 内核不支持) [v2.2.0+]。 示例:0 |
wording | Object | 无 | 自定义文案。 示例:{ 2032: '请求视频失败,请检查网络'} |
clarity | String | 'od' | 默认播放清晰度[v2.2.1+]。 示例: clarity: 'od' |
clarityLabel | Object | {od: '超清', hd: '高清', sd: '标清'} | 自定义清晰度文案 [v2.2.1+]。 示例: clarityLabel: {od: '蓝光', hd: '高清', sd: '标清'}。 |
listener | Function | 无 | 事件监听回调函数,回调函数将传入一个 JSON 格式的对象。 示例:function(msg){//进行事件处理 } |
pausePosterEnabled | Boolean | true | 暂停时显示封面[v2.3.0+]。 |
preload | String | 'auto' | 配置 video 标签的 preload 属性,只有部分浏览器生效[v2.3.0+]。 |
hlsConfig | Object | 无 | hls.js 初始化配置项[v2.3.0+]。 |
flvConfig | Object | 无 | flv.js 初始化配置项[v2.3.1+]。 |
🌰 实例方法:
方法 | 参数 | 返回值 | 说明 | 示例 |
---|---|---|---|---|
play() | 无 | 无 | 开始播放视频。 | player.play() |
pause() | 无 | 无 | 暂停播放视频。 | player.pause() |
togglePlay() | 无 | 无 | 切换视频播放状态 。 | player.togglePlay() |
mute(muted) | {Boolean} [可选] | true,false {Boolean} | 切换静音状态,不传参则返回当前是否静音。 | player.mute(true) |
volume(val) | {int} 范围:0到1 [可选] | 范围:0到1 | 设置音量,不传参则返回当前音量 。 | player.volume(0.3) |
playing() | 无 | true,false {Boolean} | 返回是否在播放中 。 | player.playing() |
duration() | 无 | {int} | 获取视频时长 。(备注:只适用于点播,需要在触发 loadedmetadata 事件后才可获取视频时长) | player.duration() |
currentTime(time) | {int} [可选] | {int} | 设置视频播放时间点,不传参则返回当前播放时间点 。(备注:只适用于点播 ) | player.currentTime() |
fullscreen(enter) | {Boolean} [可选] | true,false {Boolean} | 调用全屏接口(Fullscreen API),不支持全屏接口时使用伪全屏模式,不传参则返回值当前是否是全屏。 (备注:移动端系统全屏没有提供 API,也无法获取系统全屏状态 ) | player.fullscreen(true) |
buffered() | 无 | 0到1 | 获取视频缓冲数据百分比。 (备注:只适用于点播) | player.buffered() |
destroy() | 无 | 无 | 销毁播放器实例[v2.2.1+]。 | player.destroy() |
switchClarity() | {String}[必选] | 无 | 切换清晰度,传值 "od"、"hd"、"sd" [v2.2.1+]。 | player.switchClarity('od') |
load(url) | {String}[必选] | 无 | 通过视频地址加载视频。(备注:该方法只能加载对应播放模式下支持的视频格式,Flash 模式支持切换 RTMP、FLV、HLS 和 MP4 ,H5 模式支持 MP4、HLS 和 FLV(HLS、FLV 取决于浏览器是否支持)[v2.2.2+]) | player.load([http://xxx.mp4](http://xxx.mp4) ) |
⚙ 错误码:
Code | 提示语 | 说明 |
---|---|---|
1 | 网络错误,请检查网络配置或者播放链接是否正确。 | H5 提示的错误。 |
2 | 网络错误,请检查网络配置或者播放链接是否正确。 | 视频格式 Web 播放器无法解码。H5 提示的错误。 |
3 | 视频解码错误。 | H5 提示的错误。 |
4 | 当前系统环境不支持播放该视频格式。 | H5 提示的错误。 |
5 | 当前系统环境不支持播放该视频格式。 | 播放器判断当前浏览器环境不支持播放传入的视频,可能是当前浏览器不支持 MSE 或者 Flash 插件未启用。 |
10 | 请勿在 file 协议下使用播放器,可能会导致视频无法播放。 | - |
11 | 使用参数有误,请检查播放器调用代码。 | - |
12 | 请填写视频播放地址。 | - |
13 | 直播已结束,请稍后再来。 | RTMP 正常播放过程中触发事件(NetConnection.Connect.Closed)。Flash 提示的错误。 |
1001 | 网络错误,请检查网络配置或者播放链接是否正确。 | 网络已断开(NetConnection.Connect.Closed)。Flash 提示的错误。 |
1002 | 获取视频失败,请检查播放链接是否有效。 | 拉取播放文件失败(NetStream.Play.StreamNotFound),可能是服务器错误或者视频文件不存在。Flash 提示的错误。 |
2032 | 获取视频失败,请检查播放链接是否有效。 | Flash 提示的错误。 |
2048 | 无法加载视频文件,跨域访问被拒绝。 | 请求 M3U8 文件失败,可能是网络错误或者跨域问题。Flash 提示的错误。 |
🌈 总结
- 自从疫情后,线上直播火了。前前后后也做了好几个跟视频直播相关的项目。也踩了不少的坑,闲暇时光,回忆反思下,做笔记做总结,目的是为了便于后续开发,同时分享出来,也便于给同行一点提示。
- 前后尝试过多个视频插件,现在就使用情况和实际需求做下分析对比:
- 🐱aliplayer播放器(阿里云播放器)大厂出品,文档详细,使用人数也多:
- 兼容移动端和PC端,可自己依据文档做相应的调整和配置;
- 可以配置想要的功能性按钮;
- 可在线配置,可直接预览,效果不错;
- 不足之处就是提示信息不是很友好,自己定制错误提示的话又比较繁琐。
- 🐧TcPlayer播放器(腾讯播放器)腾讯官方出的播放器,文档相对来说没有aliplayer详细:
- 配置简单,支持移动端PC端视频点播和直播;
- 相对来说在移动端自适应效果不是很好,但可定制错误提示语;
- 相对aliplayer来说,直播中断时可以自动尝试重连,一直到有推流后自动继续直播;
- 可依据不同的状态码配置不同的错误提示语,以便于用户清晰明了了解直播状态;
- 相对aliplayer来说,直播可以暂停,aliplayer直播不能暂停;
- 🍉xgplayer播放器(西瓜播放器)字节跳动-西瓜视频的播放器,文档配置也很详细:
- 类似腾讯的TcPlayer播放器,文档也很详细;
- 可以自定义开发插件,可以截屏;
- 不足之处是直播拉流采用不同格式的地址时需要加载不同的插件,还要进行相应的配置;
🍉 西瓜播放器近期使用在了后台管理系统中用于预览视频直播和回放,后续简单的做下记录。