HTML5 Audio 的相容性問題和優化
本人在雙十一期間,做的一個移動端互動專案中,遇到一個在 App 、微信、H5頁面環境切換選擇音訊播放的功能,在測試的時候出了不少相容性問題,這裡有很多值得探索的知識,今天我們就來看一下這個 HTML5/">HTML5-Audio。
Audio 標籤用於定義聲音,比如音樂或其他音訊流,HTML5 的 Audio 標籤在很大程度上取代了 Flash 來播放音樂。
一、預設樣式
Audio 標籤在瀏覽器中的預設樣式如下圖所示,需要注意的一個地方:需要配置 controls 屬性(是否顯示預設控制條,是 Audio 標籤的控制屬性),否則不展示樣式效果。
二、Audio 支援的音訊檔案格式
1、OGG:
OGG 是一種新的音訊壓縮格式,類似於 MP3 等的音樂格式。OGG 是完全免費、開放和沒有專利限制的。OGG 檔案格式可以不斷地進行大小和音質的改良,而不影響舊有的編碼器或播放器。
2、MP3:
MP3 是一種音訊壓縮技術,其全稱是 Moving Picture Experts Group Audio Layer III(動態影像專家壓縮標準音頻層面3),簡稱為 MP3 。它被設計用來大幅度地降低音訊資料量。將音樂以 1:10 甚至 1:12 壓縮成容量較小的檔案,而對於大多數使用者來說重放的音質與最初的不壓縮音訊相比沒有明顯的下降。
3、WAV:
WAV 是微軟公司開發的一種聲音檔案格式,它用於儲存 Windows 平臺的音訊資訊資源,被 Windows 平臺及其應用程式所廣泛支援,標準格式化的 WAV 檔案和 CD 格式一樣,因此在聲音檔案質量和 CD 相差無幾。
三、相容性問題
我們來從下面幾個角度看相容性問題:
1、音訊格式的相容性
音訊格式 | Chrome | Firefox | IE9 | Opera | Safari |
---|---|---|---|---|---|
OGG | 支援 | 支援 | 支援 | 支援 | 不支援 |
MP3 | 支援 | 不支援 | 支援 | 不支援 | 支援 |
WAV | 不支援 | 支援 | 不支援 | 支援 | 不支援 |
說明:
Audio 標籤預設支援的主流的音訊檔案格式有 MP3、WAV、OGG ,不同的瀏覽器對三種格式支援程度不一樣。其中 MP3 格式支援度最好。
WAV 格式音質最好,但是檔案體積較大。MP3 壓縮率較高,普及率高,音質相比 WAV 要差。OGG 與 MP3 在相同位速率(Bit Rate)編碼的情況下,OGG 體積更小,並且 OGG 是免費的不用交專利費(這點國人很中意)。
2、不同瀏覽器對於 HTML5 Audio 標籤的相容性
說明:
在版本較新的瀏覽器中都是可以支援 Audio 標籤的,在移動端上相容性會更好一些。
四、使用方法
我們經常會使用到的屬性、方法、事件:
1、常用屬性:
屬性 | 屬性值 | 註釋 |
---|---|---|
src | url | 播放的音樂的 url 地 址(火狐只支援 OGG 的音樂,而 IE9 只支 持 MP3 格式的音樂 。chrome 貌似全支援) |
preload | preload | 預載入(在頁面被加 載時進行載入或者說 緩衝音訊),如果使用 了 autoplay 的話那麼該 屬性失效。 |
loop | loop | 迴圈播放 |
controls | controls | 是否顯示預設控制 條(控制按鈕) |
autoplay | autoplay | 自動播放 |
2、常用方法:
函式 | 作用 |
---|---|
load () | 載入音訊、視訊軟體 |
play () | 載入並播放音訊、視訊檔案或重新播放暫停的的音訊、視訊 |
pause () | 暫停當前播放的音訊 |
3、常用事件:
事件名稱 | 事件作用 |
---|---|
play | play 和 autoplay 播放時 |
pause | pause 方法觸發時 |
ended | 當前播放結束 |
timeupdate | 當前播放時間發生改變的時候(播放中常用的時間處理) |
canplaythrough | 歌曲已經載入完全完成 |
canplay | 緩衝至目前可播放狀態。 |
我們可以通過 JS 程式碼來控制播放:
五、問題與解決方案:
好的,我們再來看具體看一下 Audio 標籤的相容性問題:
1、如何解決預載入問題
現狀:preload 在 iOS 系統上的 safari 和微信是不支援的。
解決方法: 需要使用者主動觸發事件(Event) 才能進行播放。
示例程式碼:
2、如何解決多個音訊檔案切換問題
現狀:當時專案中有切換不同音樂播放,如果採用更改 Audio 標籤的 src 的方式,iOS 下會出現不能播放音樂或者播放延遲太高問題。
解決方法:這種 bug 出現的原因是音訊檔案不能快取在 iOS 系統上,每當頁面訪問其他音訊檔案時,都從網路訪問音訊檔案,解決方法:可以在頁面中 宣告多個 Audio 標籤,把需要引入的音訊檔案預先引入,播放哪個再呼叫相應檔案,這個方案的缺點是在 iOS 系統下每一個 Audio 佔一個執行緒,如果有多個的 Audio ,則很佔資源;或者把多個音訊檔案 合併成為一個檔案 ,播放其他音訊的時候只需要呼叫合併之後的音訊檔案的相應時段,雖然比較繁瑣,但是相容性很好,可以參考下該音訊合併工具(http://jsfiddle.net/aarongloege/rQv5h/light/)。
示例程式碼:
<audio src="" id="audio1"></audio>
<audio src="" id="audio2"></audio>
3、如何解決自動播放問題
現狀:iOS 端 safari 瀏覽器或者部分安卓手機的瀏覽器不支援 autoplay 屬性。
解決方法:還是 引導使用者手動觸發播放操作 。
比如繫結 touchstart 事件進行 audio.play() 操作,因此在和產品、測試同學溝通確認的時候就需要確認好這個點。如果在微信環境下可以 呼叫微信提供的外掛 ( jweixin-1.0.0.js )。
示例程式碼:
4、如何解決播放數量問題
現狀:一個 Audio 標籤只能播放一個音訊。
解決方法:如果要同時播放多個音訊,只得使用多個 Audio 標籤,但是這個情況下要注意,各瀏覽器是是支援在同一頁面播放多個音訊的,而專案場景基本只允許播放一個音訊,這個得注意 控制播放當前音樂時要停止其他音樂項的播放 。
示例程式碼:
5、如何解決移動端下音訊混合播放問題
現狀:在 iOS safari 下關閉瀏覽器視窗(切換至後臺)或者切換標籤時, Audio 仍然繼續迴圈播放音訊檔案,如果關閉瀏覽器標籤才會停止播放。
解決方法:使用 迴圈儲存時間 來檢查使用者是否在網頁上, timeupdate 事件是在音訊 Audio 的播放位置發生改變時觸發。
示例程式碼:
var loop = function (){
var music = document.getElementById('music');
this.pause();
}, false);
6、如何解決續播問題
現狀:在 JDApp 端頁面音訊播放時,切換至後臺或者其他應用,音樂暫停播放之後,再切換至音樂播放的原頁面,音樂沒有繼續播放。
解決方法:判斷是否是在 JDApp 下,如果在 JDApp 使用 JDAppUnite 呼叫原生方法 callRouterModuleWithParams 控制音訊繼續播放。
示例程式碼:
return;
// 通知原生播放狀態
7、如何解決初始化延遲問題
現狀:在 iOS safari 瀏覽器初始化一個新的音訊流時會有幾秒的延時。
解決方法:出現這 bug 的原因是因為 iOS 需要例項化一個新的音訊物件,再通過網路請求音訊資源,音訊資源載入完畢之後才能進行播放,解決方案:在 頁面 ready 之後把每個檔案都 load 一下 ,然後再呼叫 play 方法,這麼做可以使音訊資源做預載入,提前請求網路,可以具體業務場景來優化使用。
示例程式碼:
8、如何解決靜音操作問題
現狀:理想情況下使用者可以在相關頁面通過觸發事件實現音訊的靜音操作
解決方法:可以通過設定 muted 屬性來設定 Audio 靜音,但是在 iOS 8及其以下 或者 IE9 及其以下版本不支援 muted 屬性。
示例程式碼:
9、如何解決載入問題
現狀:如果在頁面未載入完成時呼叫 play 方法會失敗,在這種情況下設定 currentTime 會丟擲異常錯誤 Failed to load resource: the server responded with a status of 404 () 。
解決方法:遇到此類問題,可以先 檢查網路及音訊大小 以排除。
10、如何解決迴圈播放問題
現狀:在 iOS 系統在 5 之前不支援迴圈屬性。
解決方法:可以通過 向 onEnded 事件添加了一個事件偵聽程式 ,並在該函式中呼叫 play 方法解決。
示例程式碼:
var audio = document.getElementById('audio');
小tip:HTML5 Audio 標籤給我們提供了一些額外的資訊來指定播放哪一時間段,方法是在媒體檔案後面跟隨(“#”)格式
總結
HTML5 提供的 Audio 標籤雖然有不少的相容性問題, 但是在移動端使用音訊播放, Audio 仍然是 HTML5 發展的大勢所趨,值得我們使用。本文介紹了 Audio 標籤的使用方法以及音訊檔案的相容版本和 Audio 在不同環境下的相容性問題並相應給出瞭解決方案。最後附上自己開發的外掛
(https://github.com/jdf2e/audioCreate.js/tree/master/audiojs),
掃二維碼可訪問:
以上提到的解決方案可以幫助大家解決大多數問題,如果需要更完善的規避這些 Audio 的坑可以參考使用這個 JS 外掛,使用方法如下:
參考文獻
[1] HTML 5 audio 標籤
http://www.w3school.com.cn/html5/html5_audio.asp
[2] HTML DOM Audio 物件
http://www.w3school.com.cn/jsref/dom obj audio.asp
[3] HTML5 Audio (音訊)
http://www.runoob.com/html/html5-audio.html
[4] audio sprite 工具
http://jsfiddle.net/aarongloege/rQv5h/light/
[5] audioCreate.js
https://github.com/jdf2e/audioCreate.js/tree/master/audiojs