近日,我司的產品們又有了一個新idea,將視頻廣告與常規活動結合起來,創造更多玩法場景,以期活動收益提高。所謂是‘產品一張嘴,開發跑斷腿’。面對國內惡劣的移動端WebView環境,咱們只能快馬加鞭的去尋找一個好的解決視頻播放的方案來兼容各類移動端WebView環境和知足產品們的需求。javascript
產品對視頻廣告頁的要求有:html
HTML Video 標籤 可用於在HTML或者XHTML文檔中嵌入視頻內容。就像使用IMG標籤插入一張圖片同樣方便。寫個viedo設置一個src屬性指向視頻地址就能夠實現媒體播放了。html5
<video id="video" src="//yun.tuia.cn/jsmpeg/test.mp4" controls>
您的瀏覽器不支持Video標籤
</video>
複製代碼
controls 加上此瀏覽器將提供控件以容許用戶控制視頻播放,包括音量,搜索和暫停/恢復播放。java
在Chrome中的表現是:ios
固然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 布爾屬性,指定後,視頻會立刻自動開始播放,不會停下來等着數據載入結束。git
muted 布爾屬性,指明瞭視頻裏的音頻的默認設置。設置後,音頻會初始化爲靜音。默認值是false,意味着視頻播放的時候音頻也會播放 。github
playsinline 布爾屬性,指示視頻將「內聯」播放,即在元素的播放區域內。請注意,缺乏此屬性並不意味着視頻將始終以全屏模式播放。web
timeupdate 元素的currentTime屬性表示的時間已經改變。chrome
具體的API詳情能夠去MDN上查閱canvas
那麼咱們在來看看Video標籤和MPEG-4在移動端瀏覽器上的兼容性
MP4和MPEG-4之間的關係
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爲了避免浪費用戶的流量。移動端不容許自動播放有聲音,必須有用戶的行爲操做(如今安卓也這樣),需求中要求手機沒有進度條,不能快進,後退等直接給跪了。
見識了五花八門的移動端WebView環境下video的ui控件,我已經對此失去信心,沒法知足產品的需求。換個思路,在google上稍做搜索,便有所收穫。JSMpeg這個庫吸引了我。這個庫的大體思路就是使用js進行視頻解碼,在用canvas逐幀畫出圖像,那麼只要WebView支持canvas,就能實現視頻廣告的播放啦。
使用jsemp的優點(MPEG1 Video & MP2 Audio Decoder in JavaScript)
當他擁有前三點的時候它就已經完美的符合了咱們如今的業務需求了。
首先咱們須要對.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);
複製代碼
經過上述代碼就能夠實現視頻聲音可手動選擇禁音或者播放。
對比而言,經過使用jsmpeg解決方案仍是成功的知足了產品的需求,併成功上線投入產出,得到了預期的效果。
MPEG4 vs MP4: What Are The Differences Between MPEG4 and MP4?