h5直播活动的埋坑之旅

前言

最近参与了做空宣的H5中,里面遇到了video标签在androidiPhone 手机适配中出现了一些问题,在微信浏览器中使用android默认的播放组件,会导致video标签的层级是最高的,直播的过程中导致弹幕就不能浮现在上面了(这个是微信浏览器使用的播放内核导致的)。

HTML5-video

出现问题的原因

IOS的微信浏览器是Chrome内核, Android的微信浏览器是X5内核;由于在安卓中的微信浏览器中的层级是最高的,从而导致通过z-index层级高低的方案不能解决同时解决androidios的弹幕展现的问题。

解决方案

在解决这个问题的时候,首先在iPhone手机端通过层级的高低是可以实现弹幕在video标签上展现,但是针对android手机却是不行的,对于android手机当时讨论了三个方案:

  • 通过对展现弹幕的div框给予绝对定位,同时采用z-index的最大值进行覆盖(同时保证在同一块级格式上下文中,在android的微信浏览器中会将video标签层级展现最高)
  • 通过canvas去实现video标签的播放(但是不能转换直播过程中的链接)
  • 通过TBS(腾讯浏览器服务)中的同层浏览器来实现弹幕展现

接下来我们可以只针对android的微信浏览器来探讨和实现这个三个方案:

通过z-index来实现弹幕的层级覆盖

在这三个方案中,这个方案是最简单和最容易实现的:
HTML文件:

1
2
3
4
5
6
7
8
9

<div class = "h5-player">
<video playsinline webkit-playsinline x5-playsinline></video>
<!-- 弹幕 -->
<div class="barrage">

</div>
</div>

CSS文件:

1
2
3
4
5
6
/* 弹幕样式 */
.barrage {
position:absolute;
...
z-index:999;
}

首先要保证video和弹幕框在同一块级格式化上下文(BFC)上,然后需要弹幕框的z-index的层级高于video标签,那么就可以在ios上可以实现发送弹幕在直播中展现弹幕了,但是在android中就不能通过该方法去实现弹幕的功能,因为videoandroid中默认的层级是最高的。

通过canvas来实现弹幕的展现

首先这个方案只适用于观看回放和观看视频,不适用于视频直播。由于canvas中的drawImage方法不能转换直播过程中的视频流。以下为实现方案:

HTML文件:

1
2
3
4
5
6
7
<div class = "h5-player">
<video playsinline webkit-playsinline x5-playsinline></video>
<!-- 弹幕 -->
<div class="barrage">

</div>
</div>

CSS文件:

1
2
3
4
5
6
7
8
9
video{
display : none;
}
/* 弹幕样式 */
.barrage {
position:absolute;
...
z-index:999;
}

主要的JS部分:

1
2
3
setInterval(function(){
canvas.getContext('2d').drawImage(video,0,0);
},16);

该方法依旧需要通过z-index来实现弹幕覆盖video。通过canvas来转换目的是为了让video的层级低于弹幕层级

通过TBS中的H5同层播放器的video播放模式来实现弹幕的播放

说到用TBS的H5同层播放器来实现弹幕的播放,大家可能不是很清楚TBS是啥(腾讯浏览服务)

需要了解的话,链接地址: TBS的H5同层播放器接入规范

首先我们需要了解H5同层浏览器中的一些属性:

  • 启用H5同层浏览器(x5-video-player-type)

    1
    <video src="http://xxx.mp4" x5-video-player-type="h5"/>

    注意: 这个属性需要在播放前设置好,播放之后设置无效,下面的x5-video-player-fullscreen也是一样

  • H5同层浏览器全屏模式(x5-video-player-fullscreen

    视频播放时,进入到全屏模式:

    注意: 声明此属性,需要页面自己重新适配新的视口大小变化。可以通过监听resize 事件来实现

    1
    <video id="h5_video" src="xxx" x5-video-player-type="h5" x5-video-player-fullscreen="true"/>

    需要监听窗口大小变化(resize)实现全屏

    JS部分:

    1
    2
    3
    4
    window.onresize = function(){
    h5_video.style.width = window.innerWidth + "px";
    h5_video.style.height = window.innerHeight + "px";
    }
  • 控制横竖屏 (x5-video-orientation)

    声明播放器支持的方向, landscape 横屏, portraint竖屏

    1
    2
    3
    4
    5
    <!-- 竖屏 -->
    <video ... x5-video-player-type="h5" x5-video-orientation="portrait"/>
    <!-- 跟随手机自动旋转 -->
    <video x5-video-player-type="h5" x5-video-orientation="landscape|portrait"/>

  • 视频显示位置控制(object-position

    默认视频在指定区域的居中显示,可以通过css object-position 属性控制视频(左上角) 显示位置

  • 进入全屏通知和退出全屏通知(x5videoenterfullscreen和x5videoexitfullscreen

    示例:

    1
    2
    <video id=“myVideo".../>

    JS部分: 通过JS监听事件

    1
    2
    3
    myVideo.addEventListener("x5videoenterfullscreen|x5videoexitfullscreen", function(){
    ...
    })

前面了解到H5同层浏览器中的属性,接下来就可以实现该方案了:

要实现该方案,同样是基于第一个方案的前提下实现的,需要利用z-index的层级来实现弹幕的显示。

HTML部分:

1
2
3
<div id="h5-player">
<!-- 点击观看时,会创建一个直播组件,类名叫bjy-video -->
</div>

CSS部分同样需要将对弹幕部分进行绝对定位,还要对其进行层级设置(z-index),让其高于video的层级。

js实现部分:

在android手机中点击观看直播按钮,会开启H5同层浏览器,进入全屏模式,页面会显示video,弹幕会浮现在video上面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 观看直播
playButton.on('click', function() {
// 初始化直播组件
initH5Player();
// 开启H5同层浏览器
$('.bjy-video').attr({'x5-video-player-type':'h5','x5-video-player-fullscreen':true,'x5-video-orientation': 'portrait'});
// 设置video显示的位置, 显示在顶部
$('.bjy-video').css('object-position','0px 0px');
$('#barrage').css('display', 'block');
playButton.css('display', 'none');
// 判断手机是android还是ios来做处理
if(judgeDevice.isIOS){
$('.bjy-video').attr('controls',true)
$('.controls').css('display', 'none');
$('.ios-controls').css('display', 'flex');
$('.play-box').css('display','none')
}
if(judgeDevice.isAndroid) {
$('.controls').css('display', 'none');
}
});

//显示全屏
$('.bjy-video').on('x5videoenterfullscreen',function() {
// 显示弹幕
$('.barrage-box').css('display','block');
// 显示自定义的播放组件(全屏和弹幕的关闭和打开)
$('.controls').css('display','flex');
// 设置video标签的宽高
setTimeout(function(){
$('.bjy-video').css({
width: window.innerWidth,
height: window.innerHeight,
});
},200)
})
// 退出全屏状态
$('.bjy-video').on('x5videoexitfullscreen', function () {
$('#keeping-play').css('display','block');
$('.barrage-box').css('display','none');
$('.controls').css('display','none');
// 销毁直播流
teacherH5Player.dispose();
//清除
$('.bjy-video').css({
width: '',
height: '',
});
});

补充

如果你直接使用video标签,会出现播放video时出现自动全屏问题,video内联播放,使用以下元素都可以实现内联播放视频,
可以通过添加playsinline webkit-playsinline以及x5私有的x5-playsinline避免全屏。
ios10以上需加上playsinline属性,ios10以下需加上webkit-playsinline来实现内联播放。
按照上述属性设置之后,大多数情况都可以满足,唯独android的微信。

1
2
<video src="video/xxx.mp4" controls playsinline webkit-playsinline x5-playsinline></video>


本文由 Abert 创作,采用 知识共享署名 4.0 国际许可协议。

本站文章除注明转载/出处外,均为本站原创或翻译,转载请务必署名。