微信H5進(jìn)入默認(rèn)播放視頻

親測有效,先上效果圖

安卓機(jī)效果:



蘋果手機(jī)效果:


前言: 早期由于帶寬和流量的因素,移動端瀏覽器禁止視頻自動播放,需要用戶進(jìn)行交互才可以觸發(fā)播放,再加上安卓各個廠家對<video>標(biāo)簽的劫持,導(dǎo)致H5上自動播放視頻這個功能實現(xiàn)出現(xiàn)種種困難

通過各種途徑尋找實現(xiàn)方法及采坑,我這里整理出了一套兼容 Android/IOS 微信瀏覽器上自動播放的代碼

實現(xiàn)功能:
  • 兼容Android/IOS
  • 進(jìn)入即可自動播放
  • 取消強(qiáng)制全屏
  • 不會出現(xiàn)進(jìn)度條等控制模塊

在開始擼碼前, 我們需要說一下我們需要用到的庫:

JSMpeg

JSMpeg是用JavaScript編寫的視頻播放器。它由MPEG-TS多路分配器,MPEG1視頻和MP2音頻解碼器,WebGL和Canvas2D渲染器以及WebAudio聲音輸出組成。JSMpeg可以通過Ajax加載靜態(tài)視頻,并允許通過WebSockets進(jìn)行低延遲的流傳輸(?50ms)。
JSMpeg可以在iPhone 5S上以30fps的速度解碼720p視頻,可以在任何現(xiàn)代瀏覽器(Chrome,F(xiàn)irefox,Safari,Edge)中使用,并且壓縮后的速度僅為20kb。

簡單的說就是這個庫使用js進(jìn)行視頻解碼,再用 canvas 逐幀畫出圖像,那么只要WebView支持 canvas,就能用 JSMPeg 播放。

FFmpeg

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

FFmpeg 是一個文件轉(zhuǎn)換的工具,用這個庫把 mp4 轉(zhuǎn)成 ts 文件才能被 JSMPeg 所解析。

下載完成后, 解壓到任意目錄

進(jìn)入 /bin 文件夾,把需要用到的視頻文件拷貝進(jìn)去

打開命令行, 執(zhí)行以下代碼:

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

通用參數(shù)解釋 :
test.mp4 是視頻文件
360*640 是視頻的寬高
-r 是視頻的幀率
-b:v 視頻比特率,值越大視頻越清晰 .ts 文件體積也越大
test.ts 是轉(zhuǎn)換后的文件名(建議跟視頻文字的名字一樣)
完整參數(shù)可以參考官網(wǎng)文檔:http://ffmpeg.org/ffmpeg.html

這里參數(shù)的調(diào)整建議參考視頻本身的參數(shù)


注意命令行的代碼,一個錯誤都可能導(dǎo)致 .ts 視頻文件解析不了

命令執(zhí)行完后,會在當(dāng)前目錄創(chuàng)建轉(zhuǎn)換后的 .ts 視頻文件。

接下來進(jìn)入JSMpeg庫拿到 jsmpeg.min.js文件

這個時候我們就可以開始擼碼了

目錄結(jié)構(gòu)如下:

主要頁面代碼

<!-- 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樣式, 默認(rèn) cover
    loop: false, // 是否循環(huán), 默認(rèn)false
    autoplay: true, // 自動播放, 默認(rèn)false
    onPlay: play, // 觸發(fā)播放事件
    onPause: pause, // 觸發(fā)暫停事件
    onEnded: ended, // 觸發(fā)播放結(jié)束事件
  }

  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('視頻結(jié)束')
  }

  // console.log(player.currentTime) // 獲取視頻當(dāng)前時間
  // player.currentTime = 1 // 調(diào)整當(dāng)前視頻時間

  // console.log(player.volume) // 獲取視頻當(dāng)前音量
  // player.volume = 0; // 調(diào)整視頻聲音 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
  }
})();

關(guān)于 f-video.js,這是我自己封裝自用的一個 js 文件,里面兼容了視頻播放,暫停,結(jié)束的監(jiān)聽,以及對視頻是否靜音, 進(jìn)度條調(diào)整進(jìn)行了整合, 目前對于自己來說這些功能已經(jīng)夠用于實現(xiàn)業(yè)務(wù)了, 如果對這方面感興趣或者目前功能仍不滿足于業(yè)務(wù)的實現(xiàn), 可以參考 JSMpeg 庫提供的API進(jìn)行調(diào)整添加

采坑記錄

  • 剛開始的時候,由于沒有注意CMD命令行,打錯了命令導(dǎo)致轉(zhuǎn)碼出來的視頻播放不了,后面在JSMpeg庫的Issues才找到了問題的所在(Issues真是個好東西)
  • 之前接到過一個業(yè)務(wù),一個完全由多個視頻組成的 H5 ,當(dāng)時信心滿滿,結(jié)果做出來各種神奇的bug,播放一半卡住,切換到這個視頻不會播放,白屏等。后面排查發(fā)現(xiàn)問題是 JSMpeg 在解碼視頻的時候, 會大量占用內(nèi)存,而當(dāng)時的視頻是有7,8個,再加上微信瀏覽器不能手動釋放內(nèi)存,導(dǎo)致這些問題出現(xiàn)。所以這里建議用這種方法來實習(xí)業(yè)務(wù)的時候,最好不要處理太多視頻,否則就會出現(xiàn)上述問題。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容