移動端h5視訊方案

Yelingxiao發表於2019-03-14

前言

近日,我司的產品們又有了一個新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中的表現是:

移動端h5視訊方案
當然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在移動端瀏覽器上的相容性

移動端h5視訊方案

移動端h5視訊方案

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為了不浪費使用者的流量。移動端不允許自動播放有聲音,必須有使用者的行為操作(現在安卓也這樣),需求中要求手機沒有進度條,不能快進,後退等直接給跪了。

移動端h5視訊方案

二. 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?

相關文章