video标签

886 阅读4分钟

转载--zhuanlan.zhihu.com/p/535917105

由于video标签在各个终端表现结果大相径庭。

所以今天主要聊一下关于video标签在

浏览器/Ios、Andriod的Webview/微信环境中各个autoplay和playinle的兼容性。

首先先贴一段video标签全属性配置代码

<video
  muted /*静音播放属性,微信环境中可删除*/ 
  src="autoplay.mp4"  /*资源地址*/ 
  poster="images/poster.jpg"   /*资源封面*/ 
  preload="auto"   /*是否自动播放*/ 
  webkit-playsinline="true" /*这个属性是ios 10中设置可以让视频在小窗内播放,即不全屏播放*/  
  playsinline="true"  /*IOS微信浏览器支持小窗内播放*/ 
  x-webkit-airplay="allow" /*使此视频支持ios的AirPlay功能*/
  x5-video-player-type="h5"  /*启用H5播放器,是wechat安卓版特性*/
  x5-video-player-fullscreen="true" /*全屏设置,设置为 true 是防止横屏*/>
  x5-video-orientation="portraint" /*播放器支付的方向,landscape横屏,portraint竖屏,默认值为竖屏*/
  style="object-fit:fill"> /* 图片覆盖属性 object-fit: fill|contain|cover|scale-down|none|initial|inherit;*/>
</video>

1、autoplay自动播放属性

1.微信 (包含安卓和IOS)

可以通过微信的SKD的回调时间进行,视频的自动播放

首先引入微信的SKD链接

<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript" charset="utf-8"></script>

//也可以在这个事件触发后播放一次然后暂停(这样以后视频会处于加载状态,为后面的流畅播放做准备)
document.addEventListener("WeixinJSBridgeReady", function (){ 
    video.play();
    video.pause();//可以注释
}, false)

2.Ios 和 Andriod 浏览器(非微信、非Native Webview)
首先上答案:在安卓和IOS手机浏览器(非微信、非Native Webivew)无用户真实交互动作,不静音的情况下 自动播放是无法实现的
那退而求其次我们有哪些办法呢?
(1)静音自动播放
如果在video标签上加上muted属性,那么autoplay自动播放是可以生效。
这里要说一下,如果你想到一个曲线救国的方法:一开始静音自动播放,然后使用异步任务解除静音模式的话,也是不会生效的,比如:

setTimeout(() => {      
  let video: any = document.getElementById("video");      
  video.play();      
  video.muted = false;    
}, 5000);

可能是为了保护用户隐私或者自动播放一些用户不想影响到公众的视频原因,各设备才禁止了带声音的自动播放功能(手动[Doge])
场景:如果你的视频本身就不需要音频,那么基本问题就解决了,比如视频做背景的页面。
Tips:如果注重用户体验可以,自动播放后 给一个toast告知用户现在静音了 ,如果需要可以自行在controls放开音频。
(2)借助用户其他的实际交互动作后触发自动播放。
官方解释: requires a user gesture to play media
也是就是说需要用户的真实手势操作这样一个action才可以触发我们的自动播放。
那么这样也有了一个曲线救国的方案,比如:

//首先在视频播放页面,监听用户点击然后Play()接触无法自动播放的限制,然后马上暂停。
而后你就可以自己在任何时候调用play()自行控制播放了
var video: any = document.getElementById("video");
document.addEventListener(    
  "touchstart",   
   function () {        
    video.play();        
    video.pause();    
  },    
false);

video.play();//任何想用的时候调用

场景:视频页面首屏不需要一进入就自动播放,比如需要下滑的 视频在下方,可以利用用户滑动的事件(会触发touchstart),这样等视频dom进入可视范围的时候配合IntersectionObserver 方法去触发自动播放函数即可。
Tips:关于IntersectionObserver的使用不在这里赘述,参考:IntersectionObserver传送门

3.Ios 和 Andriod 混合开发Webview环境中(Hybrid)
首先明确:在原生native的webview中自动有声播放是可以的
(1)Ios首先按照第一步配置H5的video标签属性 ,去掉Muted属性
然后确保IOS的webview配了无需用户action播放属性,赋值为false;

//swift 代码
let theConfiguration = WKWebViewConfiguration.init()
theConfiguration.mediaPlaybackRequiresUserAction = false

然后H5部分还需要一个小细节,打开webview之后即便有autoplay属性还是需要手动触发一下代码,这边只举例一下dom操作代码,如果是react,vue,angular的可以在各自生命周期函数里去操作。

//H5代码 
setTimeout(() => {      
   var video: any = document.getElementById("video");      
   video.play();    
}, 1000);

(2)安卓首先按照第一步配置H5的video标签属性 ,去掉Muted属性即可

webview.settings.mediaPlaybackRequiresUserGesture = false //kotlin

2、playsinline行内播放属性

微信/safari/chrome按照第一部配置即可

在native webview里的话需要进行相关的一些配置即可

IOS

let theConfiguration = WKWebViewConfiguration.init()theConfiguration.allowsInlineMediaPlayback = true

Android 无需配置

3、帧动画
最后谈一下由于视频的各种表现方式的不统一(全屏播放,隐藏控制条等),以及为了追求全屏背景动画的完美效果。
如果对视频格式有极高要求的,那么还是推荐是用帧动画,当然为了性能起见推荐使用
requestAnimationFrame()函数。
当然还有另一些canvas动画库也可以实现,比如已经不维护的create.js或者pixi.js等。
这里我就不做介绍了,帧动画传送门,我看了下文章比较早,不过基本思路就是这样,把其中的setInterval换成requestAnimationFrame即可。