最近用createjs完成了個H5需求,體驗二維碼以下。在音效接入方面踩了一點坑,但...慶幸的是,坑仍是能被填上的。html
本文能爲你解決:web
IOS設備系統是不容許視頻音頻自動播放的,須要用戶明確指定播放(經過必定的交互動做),相關的音頻或視頻才能被加載。api
方法一:使用weixin提供的sdk瀏覽器
// 引入sdk <script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> var audio = (function(){ var _audio = new Audio(); _audio.src = 'xxx'; _audio.load(); return _audio; })() // 微信配置信息(即便不正確也沒問題 wx.config({ debug: false, appId: '', timestamp: 1, nonceStr: '', signature: '', jsApiList: [] }); // 在ready時觸發相關事件 wx.ready(function() { // 觸發一下play事件 audio.play(); });
方法二:野生方法微信
var audio = (function(){ var _audio = new Audio(); _audio.src = 'xxx'; _audio.load(); return _audio; })() document.addEventListener("WeixinJSBridgeReady", function () { WeixinJSBridge.invoke('getNetworkType', {}, function (e) { // 觸發一下play事件 audio.play(); }); }, false);
一、爲何推薦使用方法一?通過驗證,方法二的會在微信瀏覽器準備完成後立刻執行回調函數,假如咱們使用了第三方庫預加載音頻,在頁面監聽到WeixinJSBridgeReady
事件時,音頻因爲未加載完成,因此是獲取不到的。網絡
二、只要咱們在WeixinJSBridgeReady
OR ready
時觸發了audio.play()
事件,瀏覽器會識別到audio對象已被啓用,這樣咱們能夠在H5動畫的任意位置使用audio.play()
和audio.pause()
,而不須要再監聽用戶動做以觸發音頻播放。app
上文提到過,爲何須要音頻預加載,在動畫音效豐富的H5中,可能不止bgm一個音頻,同時,咱們還要根據場景的變換播放不一樣的音效。假如在咱們動畫播放過程當中,音頻尚未緩衝完畢,或者只緩衝了一部分,音頻是會不播放或者中止播放的。這樣,就會形成動效音效不一樣步的問題了。(在敘事性H5動畫中尤其重要dom
很簡單,直接在標籤裏使用preload,燃鵝該方法兼容性不太好,不一樣機型差別大,而且有些機型下會有preload與無preload表現一致,並不會對音頻緩衝帶來多大改善。函數
<audio src='xxx.mp3' loop=true preload='auto' />
推薦使用createjs
裏的preloadjs
,但還須要配合soundjs
使用。oop
官方文檔給出的預加載緣由,和上文提到的大同小異。
Without CreateJS, most modern browsers do a great job of loading enough audio data to play back a sound continuously until the end using HTML tags. The canplaythrough event will fire when the buffer is full, and the sound will start. This is sufficient for a click-to-play sound, or for a background sound that can start whenever its ready - but in order to play on-demand audio for games, applications, and web sites, sounds must be preloaded first.
使用
一、preloadjs + soundjs
var queue = new createjs.LoadQueue(); // 添加聲音支持 queue.installPlugin(createjs.Sound) queue.addEventListener("fileload", handleFileLoad); queue.addEventListener("complete", handleComplete); queue.loadFile({id:"bgm", src:"assets/bgm.mp3"}); // OR queue.loadManifest([ {id:"bgm", src:"assets/bgm.mp3"}, {id:"myImage2", src:"assets/image2.jpg"} ]); // 資源所有加載完成時觸發 var handleComplete = function () { // 在次調用weixinReady事件,讓瀏覽器得到音頻對象 /* 注意:音頻實例爲 var bgmInstance = createjs.Sound.play("bgm") 而後能夠經過控制 bgmInstance.play() OR bgmInstance.stop() 播放暫停音效 */ ... }
二、僅使用soundjs
// createjs.Sound.alternateExtensions = ["mp3"]; 控制音頻類型 createjs.Sound.registerSound({id:"bgm", src:"assets/bgm.mp3"}); createjs.Sound.play("bgm");
使用preloadjs
會在預加載時調用createjs.Sound.registerSound
事件註冊聲音,因此無需顯示調用。
*音頻實例類型選擇preloadjs
加載的默認音頻實例是AudioBuffer,也就是已解碼的音頻流,感興趣的同窗能夠看看api,本人對它不太瞭解,就不誤導你們了。
即:
console.log(createjs.Sound.play('bgm')) // 返回AudioBuffer實例
因此咱們不能經過audio
的api
來對它進行操做,soundjs
爲咱們提供了控制它:AbstractSoundInstance 的api
。那麼咱們還能不能經過audio dom
的方式控制呢?答案是能夠的,可是官方不推薦,而且本人在移動端也遇到獲取不到實例對象的問題,仍是稍微提一下:
// 註冊HTMLAudioPlugin,那麼將聲音註冊爲原生的audio dom createjs.Sound.registerPlugins([createjs.HTMLAudioPlugin]); // 預加載 var queue = new createjs.LoadQueue(); // 添加聲音支持 queue.installPlugin(createjs.Sound); queue.addEventListener("fileload", handleFileLoad); queue.addEventListener("complete", handleComplete); queue.loadFile({id:"bgm", src:"assets/bgm.mp3"}); // 獲取 var handleComplete = function () { var bgmAudioDom = queue.getResult('bgm'); // console.log(bgmAudioDom) 返回 <audio src='assets/bgm.mp3' loop></audio> }
// 定義loader var loader = new createjs.LoadQueue(); // 添加聲音支持 loader.installPlugin(createjs.Sound) loader.addEventListener('progress', __handleLoading); loader.addEventListener('complete', __handleComplete); loader.loadManifest(manifest); var manifest = [ {src:"plugin/bgm.mp3", id:"bgm"}, {src:"plugin/s1_female1.mp3", id:"s1_female1"}, {src:"plugin/s1_female2.mp3", id:"s1_female2"}, {src:"plugin/s1_danmu.mp3", id:"s1_danmu"}, {src:"plugin/s1_effect.mp3", id:"s1_effect"}, {src:"plugin/s3_switch.mp3", id:"s3_switch"}, ] // 加載完成 var __handleComplete = function (evt) { wx.config({ debug: false, appId: '', timestamp: 1, nonceStr: '', signature: '', jsApiList: [] }); wx.ready(function() { musicControlData['bgm'].instance = createjs.Sound.play('bgm'); musicControlData['bgm'].instance.stop(); }); }
該H5使用了preload預加載第一屏所需音效,分屏加載其餘音效的方式,因此是方法1和2結合使用的,這裏不展開敘述了,有興趣的同窗私下交流(拒絕伸手黨,禮貌微笑~
【完】