微信H5进入默认播放视频

亲测有效,先上效果图

安卓机效果:



苹果手机效果:


前言: 早期由于带宽和流量的因素,移动端浏览器禁止视频自动播放,需要用户进行交互才可以触发播放,再加上安卓各个厂家对<video>标签的劫持,导致H5上自动播放视频这个功能实现出现种种困难

通过各种途径寻找实现方法及采坑,我这里整理出了一套兼容 Android/IOS 微信浏览器上自动播放的代码

实现功能:
  • 兼容Android/IOS
  • 进入即可自动播放
  • 取消强制全屏
  • 不会出现进度条等控制模块

在开始撸码前, 我们需要说一下我们需要用到的库:

JSMpeg

JSMpeg是用JavaScript编写的视频播放器。它由MPEG-TS多路分配器,MPEG1视频和MP2音频解码器,WebGL和Canvas2D渲染器以及WebAudio声音输出组成。JSMpeg可以通过Ajax加载静态视频,并允许通过WebSockets进行低延迟的流传输(〜50ms)。
JSMpeg可以在iPhone 5S上以30fps的速度解码720p视频,可以在任何现代浏览器(Chrome,Firefox,Safari,Edge)中使用,并且压缩后的速度仅为20kb。

简单的说就是这个库使用js进行视频解码,再用 canvas 逐帧画出图像,那么只要WebView支持 canvas,就能用 JSMPeg 播放。

FFmpeg

下载地址:https://ffmpeg.zeranoe.com/builds/

FFmpeg 是一个文件转换的工具,用这个库把 mp4 转成 ts 文件才能被 JSMPeg 所解析。

下载完成后, 解压到任意目录

进入 /bin 文件夹,把需要用到的视频文件拷贝进去

打开命令行, 执行以下代码:

ffmpeg -i test.mp4 -f mpegts -vcodec mpeg1video -s 360*640 -b:v 600k -r 24 -bf 0 -codec:a mp2 -ar 44100 -ac 1 -b:a 128k test.ts

通用参数解释 :
test.mp4 是视频文件
360*640 是视频的宽高
-r 是视频的帧率
-b:v 视频比特率,值越大视频越清晰 .ts 文件体积也越大
test.ts 是转换后的文件名(建议跟视频文字的名字一样)
完整参数可以参考官网文档:http://ffmpeg.org/ffmpeg.html

这里参数的调整建议参考视频本身的参数


注意命令行的代码,一个错误都可能导致 .ts 视频文件解析不了

命令执行完后,会在当前目录创建转换后的 .ts 视频文件。

接下来进入JSMpeg库拿到 jsmpeg.min.js文件

这个时候我们就可以开始撸码了

目录结构如下:

主要页面代码

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Android/IOS微信浏览器中自动播放视频</title>
  <link rel="stylesheet" href="css/index.css">
</head>

<body>
  <div class="wrap">
    <div class="video_box"></div>
  </div>
</body>

</html>
<script src="js/vendor/jquery-3.2.1.min.js"></script>
<script src="js/vendor/jsmpeg.min.js"></script>
<script src="js/vendor/f-video.js"></script>
<script>

  let params = {
    objectFit: 'cover', // 视频的object-fit样式, 默认 cover
    loop: false, // 是否循环, 默认false
    autoplay: true, // 自动播放, 默认false
    onPlay: play, // 触发播放事件
    onPause: pause, // 触发暂停事件
    onEnded: ended, // 触发播放结束事件
  }

  let player = F_Video('media/test.mp4', params)
  $('.video_box').append(player.domElement);

  function play() {
    console.log('视频播放')
  }
  function pause() {
    console.log('视频暂停')
  }
  function ended() {
    console.log('视频结束')
  }

  // console.log(player.currentTime) // 获取视频当前时间
  // player.currentTime = 1 // 调整当前视频时间

  // console.log(player.volume) // 获取视频当前音量
  // player.volume = 0; // 调整视频声音 0-1
</script>
/* f-video.js */
let F_Video;
(function () {
  F_Video = function (url, option) {
    const u = window.navigator.userAgent.toLowerCase();
    const isAndroid = u.indexOf('android') > -1;
    let player = new Object;

    if (isAndroid) {
      let newCanvas = document.createElement('canvas');
      let params = {
        canvas: newCanvas,
        loop: option.loop || false,
        autoplay: option.autoplay || false,
        onEnded: () => {
          option.onEnded && option.onEnded();
          player.currentTime = 0;
        },
      }

      newCanvas.style.width = '100%';
      newCanvas.style.height = '100%';
      newCanvas.style.objectFit = option.objectFit || 'cover';

      player = new JSMpeg.Player(url.replace('.mp4', '.ts'), { ...option, ...params });
      player.domElement = newCanvas;
    } else {
      let newVideo = document.createElement('video');
      newVideo.setAttribute('x5-video-player-type', 'h5');
      newVideo.setAttribute('x-webkit-airplay', 'true');
      newVideo.setAttribute('airplay', 'allow');
      newVideo.setAttribute('playsinline', '');
      newVideo.setAttribute('webkit-playsinline', '');
      newVideo.setAttribute('src', url);
      option.loop && newVideo.setAttribute('loop', 'loop');
      !option.autoplay && newVideo.setAttribute('preload', 'auto')
      option.autoplay && window.WeixinJSBridge.invoke('getNetworkType', {}, (e) => { player.play(); })

      newVideo.style.width = '100%';
      newVideo.style.height = '100%';
      newVideo.style.objectFit = option.objectFit || 'cover';

      player = newVideo;
      player.domElement = newVideo;

      option.onPlay && player.addEventListener('play', option.onPlay);
      option.onPause && player.addEventListener('pause', option.onPause);
      option.onEnded && player.addEventListener('ended', option.onEnded);

    }
    return player
  }
})();

关于 f-video.js,这是我自己封装自用的一个 js 文件,里面兼容了视频播放,暂停,结束的监听,以及对视频是否静音, 进度条调整进行了整合, 目前对于自己来说这些功能已经够用于实现业务了, 如果对这方面感兴趣或者目前功能仍不满足于业务的实现, 可以参考 JSMpeg 库提供的API进行调整添加

采坑记录

  • 刚开始的时候,由于没有注意CMD命令行,打错了命令导致转码出来的视频播放不了,后面在JSMpeg库的Issues才找到了问题的所在(Issues真是个好东西)
  • 之前接到过一个业务,一个完全由多个视频组成的 H5 ,当时信心满满,结果做出来各种神奇的bug,播放一半卡住,切换到这个视频不会播放,白屏等。后面排查发现问题是 JSMpeg 在解码视频的时候, 会大量占用内存,而当时的视频是有7,8个,再加上微信浏览器不能手动释放内存,导致这些问题出现。所以这里建议用这种方法来实习业务的时候,最好不要处理太多视频,否则就会出现上述问题。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容