移动端h5视频方案

6,730 阅读7分钟

前言

近日,我司的产品们又有了一个新idea,将视频广告与常规活动结合起来,创造更多玩法场景,以期活动收益提升。所谓是‘产品一张嘴,开发跑断腿’。面对国内恶劣的移动端WebView环境,我们只能马不停蹄的去寻找一个好的解决视频播放的方案来兼容各种移动端WebView环境和满足产品们的需求。

产品对视频广告页的要求有:

  • 视频自动播放;
  • 视频页在播放过程中用户不能快进,不能暂停;
  • 视频声音可手动选择禁音或者播放;
  • 可以监听到视频已经播放结束;
  • 视频播放不卡顿,保证一定的流畅度和清晰度;

一. HTML Video 标签

HTML Video 标签 可用于在HTML或者XHTML文档中嵌入视频内容。就像使用IMG标签插入一张图片一样方便。写个viedo设置一个src属性指向视频地址就可以实现媒体播放了。

<video id="video" src="//yun.tuia.cn/jsmpeg/test.mp4" controls>
    您的浏览器不支持Video标签
  </video>

controls 加上此浏览器将提供控件以允许用户控制视频播放,包括音量,搜索和暂停/恢复播放。

在Chrome中的表现是:

当然Video标签可设置的属性还有很多,为了满足业务需求我添加了一些属性:

<video
    id="video"
    src="//yun.tuia.cn/jsmpeg/test.mp4"
    autoplay
    muted
    webkit-playsinline
    playsinline
    x5-playsinline
    style="width:100%;">
    您的浏览器不支持Video标签
 </video>
let videoEle = document.querySelector('#video');
videoEle.addEventListener('timeupdate', function() {
    console.log(this.currentTime);
})
videoEle.addEventListener('click', function() { this.muted = !this.muted })

autoplay 布尔属性,指定后,视频会马上自动开始播放,不会停下来等着数据载入结束。

muted 布尔属性,指明了视频里的音频的默认设置。设置后,音频会初始化为静音。默认值是false,意味着视频播放的时候音频也会播放 。

playsinline 布尔属性,指示视频将“内联”播放,即在元素的播放区域内。请注意,缺少此属性并不意味着视频将始终以全屏模式播放。

timeupdate 元素的currentTime属性表示的时间已经改变。

具体的API详情可以去MDN上查阅

那么我们在来看看Video标签和MPEG-4在移动端浏览器上的兼容性

MP4和MPEG-4之间的关系

  • MP4是MPEG-4 Part 14(不适用于MPEG4)的缩写。它可以是视频文件扩展名(.mp4),用于存储视频和音频数据的容器格式,以及视频格式。
  • MPEG-4:它是MPEG组的压缩方法,专为低带宽(低于1.5MBit / sec比特率)视频/音频编码而设计。

MP4是MPEG-4的媒体容器格式之一。除此之外,以MPEG-4编码的视频还具有其他媒体容器格式,如Matroska(MKV),AVI,MXF,Ogg和QuickTime。

有个公式显示为:媒体容器=视频格式(视频编解码器)+音频格式(音频编解码器)+字幕

那么:MP4(.mp4)= MP4视频格式(.mpeg4 / .h264视频编解码器)+音频格式(mp3,aac等)+字幕

MPEG-4 和 MP4的具体差异可以访问这篇文章:MPEG4 vs MP4: What Are The Differences Between MPEG4 and MP4?

通过上面可以看到,目前MP4和video各浏览器的兼容较好。当我了解到这,多么令人喜悦啊!直接可以应用了啊!产品的需求满足了呀!但是,理想很丰满,现实很残酷,当我以为我在chrome和ios上的safari上完美实现方案的时候,各大安卓手机的WebView和微信环境给我了我沉重的打击。 各个手机厂商的浏览器和app自己封装的WebView对于video播放器真的百花齐放呀(各个手机厂家有各个厂家的控件UI,还有不同app内WebView,效果也不一样)起初ios为了不浪费用户的流量。移动端不允许自动播放有声音,必须有用户的行为操作(现在安卓也这样),需求中要求手机没有进度条,不能快进,后退等直接给跪了。

二. JSMpeg 方案

见识了五花八门的移动端WebView环境下video的ui控件,我已经对此失去信心,无法满足产品的需求。换个思路,在google上稍作搜索,便有所收获。JSMpeg这个库吸引了我。这个库的大致思路就是使用js进行视频解码,在用canvas逐帧画出图像,那么只要WebView支持canvas,就能实现视频广告的播放啦。

使用jsemp的优势(MPEG1 Video & MP2 Audio Decoder in JavaScript)

  1. 适用于所有现代浏览器的视频和音频格式。
  2. 没有许可费。所有MPEG1和MP2专利均已过期。
  3. 非常严格地控制音频和视频解码器以实现您的想法。
  4. 具有高帧速率和可接受的质量和比特率的极低延迟实时流。
  5. 您可以从上到下理解的堆栈。

当他拥有前三点的时候它就已经完美的符合了我们现在的业务需求了。

首先我们需要对.mp4的视频进行转码转成.ts文件

JSMpeg仅支持使用MPEG1视频编解码器和MP2音频编解码器播放MPEG-TS容器。视频解码器无法正确处理B帧(尽管默认情况下似乎没有现代编码器使用这些),并且视频的宽度必须是2的倍数。

我们可以使用这个转换视频格式、生成视频流的神器 : FFmpeg

.ts和.mp4一样都是一种媒体容器, .ts和.mp4的区别主要表现为两者的封装形式不同

您可以使用ffmpeg对合适的视频进行编码,如下所示:

ffmpeg -i in.mp4 -f mpegts -codec:v mpeg1video -codec:a mp2 -b 0 out.ts

您还可以控制视频大小(-s),帧速率(-r),视频比特率(-b:v),音频比特率(-b:a),音频通道数(-ac),采样率(-ar)等等。有关详细信息,请参阅FFmpeg文档。

ffmpeg -i in.mp4 -f mpegts \
	-codec:v mpeg1video -s 960x540 -b:v 1500k -r 30 -bf 0 \
	-codec:一个mp2 -ar 44100 -ac 1 -b:一个128k \
	out.ts
比如你想提高视频的比特率(清晰度)就能将 -b:v 5000k 但是相应的.ts文件体积也会变大

JSMpeg的引入方式只能通过在html中加载源文件:

<script  src = “ jsmpeg.min.js ”> </ script >

JSMpeg使用:

<p>jsmpeg解决方案</p>
<canvas id="canvas" style="width: 100vw;"></canvas>
<div id="ua"></div>
<script src="http://yun.tuia.cn/jsmpeg/jsmpeg.min.js"></script>
var player = new JSMpeg.Player('//yun.dui88.com/jsmpeg/test.ts', {
        disableGl: true,
        disableWebAssembly: true,
        loop: false,
        autoplay: true,
        canvas: document.querySelector('#canvas'),
        onEnded: () => {
            console.log('JSMpeg already end')
        }
    });
document.querySelector('#ua').innerHTML = navigator.userAgent

上述代码就可以使视频转成canvas播放了并且视频自动播放,视频页在播放过程中用户不能快进,不能暂停,可以监听到视频已经播放结束。

 // 为统一用户交互即muted(静音)自动播放,Android系统下未使用chromium M71版本的webview仍不支持autoplay策略(浏览器市场占比较大)。
    function toggleVolumn() {
      // 如果是依据autoplay policy而消音
      if (!player.audioOut.unlocked) {
        // 解除消音
        player.audioOut.unlock();
        // 避免一些隐患手动设置volume
        player.audioOut.volume = 1;
      } else {
        player.volume = player.volume > 0 ? 0 : 1;
      }
    }
    document.querySelector('#canvas').addEventListener('click', toggleVolumn, true);

通过上述代码就可以实现视频声音可手动选择禁音或者播放。

结论

  • 即使W3C API标准也越来越完美了,但是大部分的设备、浏览器、WebView厂商在标准的支持上也各有各的想法,制定这自己的规范标准,导致出现了很多不同的Ui风格。
  • JSMpeg在各种机型、浏览器、和WebView环境下展现出极好的Ui统一,并且拥有很多API可以控制视频,音频,足够满足业务需求。
  • 由于JSMpeg采取分段传输加载,所以首次加载视频播放速度比video快,但中间网络波动会使视频卡顿。
  • 将.mp4格式文件转成.ts使文件体积变大。
  • 部分浏览器版本和WebView出现音画不同步的情况。

对比而言,通过使用jsmpeg解决方案还是成功的满足了产品的需求,并成功上线投入产出,获得了预期的效果。

相关文章

Decode It Like It's 1999

H5-Video 能做的事&存在的坑

HTML5 视频直播(二)

MDN

MPEG4 vs MP4: What Are The Differences Between MPEG4 and MP4?