原生video在手机浏览器中各个属性以及获取视频尺寸和自动播放
内联播放效果
HTML5标签video在PC上显示很简单,就一个标签加资源,很少需要关心其它属性。但放到移动设备上,video的标准,Android和iOS有很多区别,另外还有很多各家浏览器特定的属性,本文详细讲了video在移动端的实践。
先来看一个例子:视频内联播放案例
<video id="testVideo1"
x-webkit-airplay="true"
x5-playsinline="true"
playsinline="true"
webkit-playsinline="true"
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x5-video-orientation="portraint"
controls="true"
src="http://v.qdxin.cn/v/2021/20210430-pingdudaodeyinhang-s.mp4"
height="220"
></video>
功能属性分析
抛去常规的id、height等等看一眼便知道的属性外,我们来看看其他的:
controls
加上这个属性,Gecko 会提供用户控制,允许用户控制视频的播放,包括音量,跨帧,暂停/恢复播放。
poster
属性规定视频下载时显示的图像,或者在用户点击播放按钮前显示的图像。如果未设置该属性,则使用视频的第一帧来代替。关于poster也有一些知识点,请参考我的另一篇文章《video标签的预览图poster常见问题》。
x5-video-player-type="h5"
启用H5播放器,是wechat安卓版特性。启用同层H5播放器,就是在视频全屏的时候,div可以呈现在视频层上,也是WeChat安卓版特有的属性。同层播放别名也叫做沉浸式播放,播放的时候看似全屏,但是已经除去了control和微信的导航栏,只留下"X"和"<"两键。目前的同层播放器只在Android(包括微信)上生效,暂时不支持iOS。
x5-video-player-fullscreen="true"
全屏设置。它又两个属性值,ture和false,true支持全屏播放,false不支持全屏播放。其实,IOS 微信浏览器是Chrome的内核,相关的属性都支持,也是为什么X5同层播放不支持的原因。安卓微信浏览器是X5内核,一些属性标签比如playsinline就不支持,所以始终全屏【2021年7月7日测试,安卓机微信均已内联播放】。
x5-video-orientation="portraint"
播放器支付的方向,landscape横屏,portraint竖屏,默认值为竖屏。
playsinline="true"
IOS微信浏览器支持小窗内播放,同理,webkit-playsinline="true" 也是同样功能。
视频播放时局域播放,不脱离文档流 。但是这个属性比较特别, 需要嵌入网页的APP比如WeChat中UIwebview 的allowsInlineMediaPlayback = YES webview.allowsInlineMediaPlayback = YES,才能生效。换句话说,如果APP不设置,你页面中加了这标签也无效,这也就是为什么安卓手机WeChat 播放视频总是全屏,因为APP不支持playsinline,而ISO的WeChat却支持。【经过测试截止到2021年7月7日,安卓版的微信也视频播放时不在全屏了,均为内联播放,确切结果待测试】
这里就要补充下,如果是想做全屏直播或者全屏H5体验的用户,IOS需要设置删除 webkit-playsinline 标签,因为你设置 false 是不支持的。但是安卓上测试去掉后,依然会内联播放。
x-webkit-airplay="allow"
这个属性应该是使此视频支持ios的AirPlay功能。使用AirPlay可以直接从使用iOS的设备上的不同位置播放视频、音乐还有照片文件,也就是说通过AirPlay功能可以实现影音文件的无线播放,当然前提是播放的终端设备也要支持相应的功能。
自动播放
目前手机和PC都不能自动播放,仅仅在微信中可以实现:
document.addEventListener("WeixinJSBridgeReady", function (){
video.play();
}, false)
微信提供了一个事件WeixinJSBridgeReady,在微信嵌入webview全局的这个事件触发后,视频仍可以自动播放,这个应该是现在在ios端微信的视频自动播放的比较靠谱的方式,其他如手q或者其他浏览器,建议就引导用户出发触屏的行为操作出发比较好。
播放控制
对于video或者audio等媒体元素,有一些方法,常用的有play(),pause();也有一些事件,
在移动端有一些坑需要注意,不要轻易使用媒体元素的除'ended','timeupdate'以外event事件,在不同的机子上可能有不同的情况产生,例如:ios下监听'canplay'和'canplaythrough'(是否已缓冲了足够的数据可以流畅播放)当加载时是不会触发的,即使preload="auto"也没用,但在pc的chrome调试器下和android下,是会在加载阶段就触发。ios需要播放后才会触发。
总之就是现在的视频标准还不尽完善,有很多坑要注意,要使用前最好自己亲测一遍 就是当第一次播放视频的时候ios端,如果网络慢,视频从开始播到能展现画面会有短暂的黑屏(处理视频源数据的时间),为了避免这个黑屏,可以在视频上加个div浮层(可以一个假的视频第一帧),然后用timeupdate方法监听,视屏播放及有画面的时候再移除浮层。
video.addEventListener('timeupdate', function (){
//当视频的currentTime大于0.1时表示黑屏时间已过,已有视频画面,可以移除浮层(.pagestart的div元素)
if ( !video.isPlayed && this.currentTime>0.1 ){
$('.pagestart').fadeOut(500);
video.isPlayed = !0;
}
})
获取视频真正的尺寸
由于canplay事件在ios上不生效,因此,就要换一种方法(以vue为例):
<video @durationchange="canPlayVideo"></video>
canPlayVideo(e) {
// console.log(e.target.videoWidth, e.target.videoHeight)
console.log(e)
if(e.target.videoHeight >= e.target.videoWidth) {
// 竖版视频
} else {
// 横版视频
}
}
在ios上,要使用durationchange钩子函数,在这个阶段去获取视频真正的尺寸。
去掉video的controls中的下载按钮
video::-internal-media-controls-download-button {
display:none;
}
video::-webkit-media-controls-enclosure {
overflow:hidden;
}
video::-webkit-media-controls-panel {
width: calc(100% + 30px);
}