Audio 標(biāo)簽用于定義聲音修噪,比如音樂或其他音頻流知纷,HTML5 的 Audio 標(biāo)簽在很大程度上取代了 Flash 來播放音樂呆抑。
一是辕、默認(rèn)樣式
Audio 標(biāo)簽在瀏覽器中的默認(rèn)樣式如下圖所示,需要注意的一個(gè)地方:需要配置controls屬性(是否顯示默認(rèn)控制條昙啄,是 Audio 標(biāo)簽的控制屬性)穆役,否則不展示樣式效果。
二梳凛、Audio 支持的音頻文件格式
1耿币、OGG:
OGG 是一種新的音頻壓縮格式,類似于 MP3 等的音樂格式韧拒。OGG 是完全免費(fèi)淹接、開放和沒有專利限制的。OGG 文件格式可以不斷地進(jìn)行大小和音質(zhì)的改良叛溢,而不影響舊有的編碼器或播放器塑悼。
2、MP3:
MP3 是一種音頻壓縮技術(shù)楷掉,其全稱是 MovingPictureExpertsGroupAudioLayerIII(動(dòng)態(tài)影像專家壓縮標(biāo)準(zhǔn)音頻層面3)厢蒜,簡(jiǎn)稱為 MP3 。它被設(shè)計(jì)用來大幅度地降低音頻數(shù)據(jù)量烹植。將音樂以 1:10 甚至 1:12 壓縮成容量較小的文件斑鸦,而對(duì)于大多數(shù)用戶來說重放的音質(zhì)與最初的不壓縮音頻相比沒有明顯的下降。
3草雕、WAV:
WAV 是微軟公司開發(fā)的一種聲音文件格式鄙才,它用于保存 Windows 平臺(tái)的音頻信息資源,被 Windows 平臺(tái)及其應(yīng)用程序所廣泛支持促绵,標(biāo)準(zhǔn)格式化的 WAV 文件和 CD 格式一樣攒庵,因此在聲音文件質(zhì)量和 CD 相差無幾嘴纺。
三、兼容性問題
我們來從下面幾個(gè)角度看兼容性問題:
1浓冒、音頻格式的兼容性
音頻格式ChromeFirefoxIE9OperaSafari
OGG支持支持支持支持不支持
MP3支持不支持支持不支持支持
WAV不支持支持不支持支持不支持
說明:
Audio 標(biāo)簽?zāi)J(rèn)支持的主流的音頻文件格式有 MP3栽渴、WAV、OGG 稳懒,不同的瀏覽器對(duì)三種格式支持程度不一樣闲擦。其中 MP3 格式支持度最好。
WAV 格式音質(zhì)最好场梆,但是文件體積較大墅冷。MP3 壓縮率較高,普及率高或油,音質(zhì)相比 WAV 要差寞忿。OGG 與 MP3 在相同位速率(Bit Rate)編碼的情況下,OGG 體積更小顶岸,并且 OGG 是免費(fèi)的不用交專利費(fèi)(這點(diǎn)國(guó)人很中意)腔彰。
2、不同瀏覽器對(duì)于 HTML5 Audio 標(biāo)簽的兼容性
說明:
在版本較新的瀏覽器中都是可以支持 Audio 標(biāo)簽的辖佣,在移動(dòng)端上兼容性會(huì)更好一些霹抛。
四、使用方法
我們經(jīng)常會(huì)使用到的屬性卷谈、方法杯拐、事件:
1、常用屬性:
屬性屬性值注釋
srcurl播放的音樂的 url 地址(火狐只支持 OGG 的音樂世蔗,而 IE9 只支持 MP3 格式的音樂端逼。chrome 貌似全支持)
preloadpreload預(yù)加載(在頁面被加載時(shí)進(jìn)行加載或者說緩沖音頻),如果使用了 autoplay 的話那么該屬性失效凸郑。
looploop循環(huán)播放
controlscontrols是否顯示默認(rèn)控制條(控制按鈕)
autoplayautoplay自動(dòng)播放
2裳食、常用方法:
函數(shù)作用
load()加載音頻矛市、視頻軟件
play()加載并播放音頻芙沥、視頻文件或重新播放暫停的的音頻、視頻
pause()暫停當(dāng)前播放的音頻
3浊吏、常用事件:
事件名稱事件作用
playplay 和 autoplay 播放時(shí)
pausepause 方法觸發(fā)時(shí)
ended當(dāng)前播放結(jié)束
timeupdate當(dāng)前播放時(shí)間發(fā)生改變的時(shí)候(播放中常用的時(shí)間處理)
canplaythrough歌曲已經(jīng)載入完全完成
canplay緩沖至目前可播放狀態(tài)而昨。
我們可以通過 JS 代碼來控制播放:
let audio = document.getElementById('audio');audio.load();//加載audio.play();//播放audio.pause();//暫停audio.loop = true;//循環(huán)播放
五、問題與解決方案:
好的找田,我們?cè)賮砜淳唧w看一下 Audio 標(biāo)簽的兼容性問題:
1歌憨、如何解決預(yù)加載問題
現(xiàn)狀:preload 在 iOS 系統(tǒng)上的 safari 和微信是不支持的。
解決方法:需要用戶主動(dòng)觸發(fā)事件(Event)才能進(jìn)行播放墩衙。
示例代碼:
$("#btn").click(function() {? ? $("#audio").load();})
2务嫡、如何解決多個(gè)音頻文件切換問題
現(xiàn)狀:當(dāng)時(shí)項(xiàng)目中有切換不同音樂播放甲抖,如果采用更改 Audio 標(biāo)簽的 src 的方式,iOS 下會(huì)出現(xiàn)不能播放音樂或者播放延遲太高問題心铃。
解決方法:這種 bug 出現(xiàn)的原因是音頻文件不能緩存在 iOS 系統(tǒng)上准谚,每當(dāng)頁面訪問其他音頻文件時(shí),都從網(wǎng)絡(luò)訪問音頻文件去扣,解決方法:可以在頁面中聲明多個(gè) Audio標(biāo)簽柱衔,把需要引入的音頻文件預(yù)先引入,播放哪個(gè)再調(diào)用相應(yīng)文件愉棱,這個(gè)方案的缺點(diǎn)是在 iOS 系統(tǒng)下每一個(gè) Audio 占一個(gè)線程唆铐,如果有多個(gè)的 Audio ,則很占資源奔滑;或者把多個(gè)音頻文件合并成為一個(gè)文件艾岂,播放其他音頻的時(shí)候只需要調(diào)用合并之后的音頻文件的相應(yīng)時(shí)段,雖然比較繁瑣档押,但是兼容性很好澳盐,可以參考下該音頻合并工具(http://jsfiddle.net/aarongloege/rQv5h/light/)。
示例代碼:
<audio src="" id="audio1"></audio><audio src="" id="audio2"></audio>var audio1 = document.getElementById('audio1');var audio2 = document.getElementById('audio2');audio1.play();audio2.play();
3令宿、如何解決自動(dòng)播放問題
現(xiàn)狀:iOS 端 safari 瀏覽器或者部分安卓手機(jī)的瀏覽器不支持 autoplay 屬性叼耙。
解決方法:還是引導(dǎo)用戶手動(dòng)觸發(fā)播放操作。 比如綁定 touchstart 事件進(jìn)行 audio.play() 操作粒没,因此在和產(chǎn)品筛婉、測(cè)試同學(xué)溝通確認(rèn)的時(shí)候就需要確認(rèn)好這個(gè)點(diǎn)。如果在微信環(huán)境下可以調(diào)用微信提供的插件( jweixin-1.0.0.js )癞松。
示例代碼:
wx.ready(function() {? ? audio.play();});
4爽撒、如何解決播放數(shù)量問題
現(xiàn)狀:一個(gè) Audio 標(biāo)簽只能播放一個(gè)音頻。
解決方法:如果要同時(shí)播放多個(gè)音頻响蓉,只得使用多個(gè) Audio 標(biāo)簽硕勿,但是這個(gè)情況下要注意,各瀏覽器是是支持在同一頁面播放多個(gè)音頻的枫甲,而項(xiàng)目場(chǎng)景基本只允許播放一個(gè)音頻源武,這個(gè)得注意控制播放當(dāng)前音樂時(shí)要停止其他音樂項(xiàng)的播放。
示例代碼:
<audio src="a.mp3" src="a.mp3"></audio><audio src="b.mp3" src="b.mp3"></audio><audio src="c.mp3" src="c.mp3"></audio>
5想幻、如何解決移動(dòng)端下音頻混合播放問題
現(xiàn)狀:在 iOS safari 下關(guān)閉瀏覽器窗口(切換至后臺(tái))或者切換標(biāo)簽時(shí)粱栖, Audio 仍然繼續(xù)循環(huán)播放音頻文件,如果關(guān)閉瀏覽器標(biāo)簽才會(huì)停止播放脏毯。
解決方法:使用循環(huán)存儲(chǔ)時(shí)間來檢查用戶是否在網(wǎng)頁上闹究,timeupdate事件是在音頻 Audio 的播放位置發(fā)生改變時(shí)觸發(fā)。
示例代碼:
var lastSeen;var loop = function (){? lastSeen = Date.now();? setTimeout(loop, 50);};loop();var music = document.getElementById('music');music.addEventListener('timeupdate', function (){? if(Date.now() - lastSeen > 100){? ? this.pause();? }}, false);
6食店、如何解決續(xù)播問題
現(xiàn)狀:在 JDApp 端頁面音頻播放時(shí)渣淤,切換至后臺(tái)或者其他應(yīng)用赏寇,音樂暫停播放之后,再切換至音樂播放的原頁面价认,音樂沒有繼續(xù)播放蹋订。
解決方法:判斷是否是在 JDApp 下,如果在 JDApp 使用JDAppUnite調(diào)用原生方法 callRouterModuleWithParams 控制音頻繼續(xù)播放刻伊。
示例代碼:
function toOriginalChk(wvt, soundRouter) {? // 判斷環(huán)境? if (wvt == 'notJdApp') {? ? return;? } else if (wvt == 'wk') {? ? // 通知原生播放狀態(tài)? ? window.webkit.messageHandlers.JDAppUnite.postMessage({? ? ? 'method': 'callRouterModuleWithParams',? ? ? 'params': JSON.stringify(soundRouter)? ? });? } else if (wvt == 'ui') {? ? window.JDAppUnite && window.JDAppUnite.callRouterModuleWithParams(JSON.stringify(soundRouter));? }}
7露戒、如何解決初始化延遲問題
現(xiàn)狀:在 iOS safari 瀏覽器初始化一個(gè)新的音頻流時(shí)會(huì)有幾秒的延時(shí)。
解決方法:出現(xiàn)這 bug 的原因是因?yàn)?iOS 需要實(shí)例化一個(gè)新的音頻對(duì)象捶箱,再通過網(wǎng)絡(luò)請(qǐng)求音頻資源智什,音頻資源加載完畢之后才能進(jìn)行播放,解決方案:在頁面 ready 之后把每個(gè)文件都 load 一下丁屎,然后再調(diào)用 play 方法荠锭,這么做可以使音頻資源做預(yù)加載,提前請(qǐng)求網(wǎng)絡(luò)晨川,可以具體業(yè)務(wù)場(chǎng)景來優(yōu)化使用证九。
(3) 示例代碼:
$(function() {? $("#audio1").load();? $("#audio2").load();})
8、如何解決靜音操作問題
現(xiàn)狀:理想情況下用戶可以在相關(guān)頁面通過觸發(fā)事件實(shí)現(xiàn)音頻的靜音操作
解決方法:可以通過設(shè)置 muted 屬性來設(shè)置 Audio 靜音共虑,但是在 iOS 8及其以下 或者 IE9 及其以下版本不支持 muted 屬性愧怜。
示例代碼:
$("#audio").muted = true
9、如何解決加載問題
現(xiàn)狀:如果在頁面未加載完成時(shí)調(diào)用 play 方法會(huì)失敗妈拌,在這種情況下設(shè)置 currentTime 會(huì)拋出異常錯(cuò)誤Failed to load resource: the server responded with a status of 404 ()拥坛。
解決方法:遇到此類問題,可以先檢查網(wǎng)絡(luò)及音頻大小以排除尘分。
10猜惋、如何解決循環(huán)播放問題
現(xiàn)狀:在 iOS 系統(tǒng)在 5 之前不支持循環(huán)屬性。
解決方法:可以通過向 onEnded 事件添加了一個(gè)事件偵聽程序培愁,并在該函數(shù)中調(diào)用 play 方法解決著摔。
示例代碼:
var audio = document.getElementById('audio');audio.play();var onEnded = function() {? this.play();};audio.addEventListener('ended', onEnded, false);
小tip:HTML5 Audio 標(biāo)簽給我們提供了一些額外的信息來指定播放哪一時(shí)間段,方法是在媒體文件后面跟隨(“#”)格式
<audio src="audio.mp3#t=10,20"></audio>// src="audio.mp3#t=10,20" (從10s播放到20s)// src="audio.mp3#t=10" (從10s播放到完)// src="audio.mp3#t=,10" (從開頭播放到10s)