我们具体问题具体分析,在调研(谷歌)了一波之后,发现存在三种场景:

  1. safari
  2. 微信
  3. 我们的app

这其实有三种不同的解决方案,我们简略的说一下前两种,重点说下我们app内的解决

Safari

给video标签加一个playsinline属性即可。
ios11开始,ios支持通过playsinline在自带的safari中进行行内播放,ios9和ios10的微信,仍需带前缀的webkit-playsinline,所以保险起见,两个都加上。

  1. <video muted
  2. poster="https://cdn.dewu.com/node-common/6fec58c9-f52e-8fa6-e9e3-70b728a6e74c.png "
  3. src="https://cdn.poizon.com/node-common/2c9de5eae0c4759316d3b42b0a7b372a.mp4"
  4. webkit-playsinline="true"
  5. playsinline
  6. ><video>

微信

微信加两个属性,x5-video-player-type=”h5” x5-video-player-fullscreen=”portraint”
根据x5内核的文档,他们使用x5-video-player-type=’h5-page’属性来控制网页内部同层播放,可以在视频上方显示html元素。x5-video-player-fullscreen 属性控制是否进入全屏模式,同样是微信x5内核专用,如果不申明此属性,页面得到视口区域为原始视口大小(视频未播放前),比如在微信里,会有一个常驻的标题栏,如果不声明此属性,这个标题栏高度不会给页面,播放时会平均分为两块(上下黑块)。

  1. <video muted
  2. poster="https://cdn.dewu.com/node-common/6fec58c9-f52e-8fa6-e9e3-70b728a6e74c.png "
  3. src="https://cdn.poizon.com/node-common/2c9de5eae0c4759316d3b42b0a7b372a.mp4"
  4. type="video/mp4"
  5. webkit-playsinline="true"
  6. playsinline=""
  7. x5-video-player-type="h5"
  8. x5-video-player-fullscreen="portraint"
  9. ></video>

APP内

中间方案:iphone-inline-video

一个2k start的库,可以做到ios行内播放。原理很简单,用自定义的play方法替换了原生的,逐帧对video的currentTime进行写入,相当于播放的并不是视频流而是ppt。
也因此性能不是很好,理论上来说低端安卓机会卡死无法播放,没有的原因也很简单,if (安卓判断) return
并且一个致命的问题是,实测使用这个库时,即使muted也无法自动播放,必须要用户手势触发,这一步会导致用户流失,不建议使用。
核心代码:
image.png
image.png
image.png

jsmpeg

赫赫有名(5.3k star)的视频解析库,可用于视频直播或点播,特色是高兼容、低延迟。原理是通过拉取视频流,将其用webGL一帧帧渲染在页面上。跟set video.currentTime相比,直接操作更底层的要素,所以性能相对好一些。
使用时需要注意:

  1. jsmpeg只能解析.ts文件,而且是规范的ts文件,所以需要自己做先行转换,建议使用ffmpeg。
  2. 转换的指令如下(需要先安装ffmpeg):

    1. ffmpeg -i in.mp4 -f mpegts \
    2. -codec:v mpeg1video -s 960x540 -b:v 1500k -r 30 -bf 0 \
    3. -codec:a mp2 -ar 44100 -ac 1 -b:a 128k \
    4. out.ts
  3. 这里注意,转换的时候尺寸(例如这里是 960x540),转换前后一定要一样,不然转换出来的视频会有问题。

  4. 可以通过 ffmpeg -i xx.mp4 获取到视频的尺寸

    最终方案:App修改webview配置

    对应功能已在4.73版本上线,只需要在url上加上参数 ?isAllowVideoAutoPlay=1 即可使用
    该方案为跨端方案,需要和客户端配合。因为在app内我们的宿主环境是webview也就是app,webview设置当然比我们的层级要高。所以只需要app按照以下设置即可:
    1. // 允许内联,否则我们的app里面会全屏播放
    2. webview.allowsInlineMediaPlayback = true
    3. // 如果这个属性不设置为false,则无法自动播放,需要用户手动点击播放
    4. webview.mediaPlaybackRequiresUserAction = false