2012年11月3日 星期六

LimeJS : HTML5 的 Audio

2012年11月3日 星期六
LimeJS 來開發 HTML5 的程式,可以省去不少處理 CSS 及物件......的麻煩,而且用起來和其它 framework 類似,日後要轉換陣地,應該會較容易一些。不過,它對於文字、圖形或是動畫等,功能較完整,聲音、影片這一塊就相對單薄了些。把這幾天玩 Audio 的一些心得暫時記錄一下。

首先,在 iPad (iOS) 的 Safari 有一點很特別,根據 Apple 官方文件:
中所述,基於保護使用者的權益,如果使用者沒有「按按鈕」,Safari 不會自動載入 Audio 或 Video。這也是為什麼我們新增一個 Audio 物件後,即使在程式中下了 play() 指令,它不會開始播放聲音的原因。必須把 play() 指令放到滑鼠或觸控的事件中,被動的由使用者去觸發過它,才能開始載入檔案並播放聲音。另外,iOS 無法同時播放多個聲音檔,一次只允許播放一個聲音。因此,給 iOS 用的,要考慮這兩點。
如果是要當遊戲音效,iOS 不會自動播放,那不就白搭了?沒關係,我的做法是,在程式最前面放一個使用說明的畫面,要使用者按下按鈕後才開始玩,就利用這個機會,順便由使用者手動執行了一次 play() 指令,這樣,之後要播放聲音,只要用同一個 Audio 更改 src ,指定別的聲音檔,就不再受要使用者按按鈕才能載入並播放的限制了。

LimeJS 中的 Audio 使用 lime.audio.Audio ,它只提供了基本的 play , stop 及兩個用來顯示狀態的 isLoaded 和 isPlaying。如果,想用前述的方法,只重新指定 Audio 檔案的路徑,就得自己再將 lime.audio.Audio 增強。

底下 w3schools 的文件很有參考價值:
例如,假設我用 
var sound = new lime.audio.Audio('test.mp3'); 
加了一個聲音物件載入 test.mp3 檔案,想要取得聲音檔的總長度(秒)及已播放的時間(秒),可以利用下面的語法得到:
  • sound.baseElement.duration
  • sound.baseElement.currentTime
那個「.baseElement」是關鍵,它是「HTMLAudioElement」,所有操作都是針對它。

想要指定另外一個聲音檔,可以利用下面的語法:
sound.baseElement.src = 'theSecondSound.mp3';
當然,我們也可以用來監聽「事件」,寫一些對應的功能,例如,想製作一個播放時間的指示器,就可以監聽「timeupdate」,例如:
goog.events.listen(sound.baseElement,'timeupdate',function(){
......
......
});
當聲音在播放時,會去執行 ...... 所指定的程式碼,如果配合取得 sound.baseElement.duration 及 sound.baseElement.currentTime 的值並加以計算,即可顯示播放狀態。

另外,如果我們在新建完 Audio 物件後,在它還沒有載入完成就馬上執行 play() 的播放指令,也會失敗。「canplay」事件是在已經準備就緒時觸發的事件,可以好好好的利用。

透過 w3schools 的參考文件,對於 Audio 的操作,已能掌握大部份。目前尚不知如何以 base64 來將 mp3 檔案編碼後直接餵給 iOS 的 Safari ,如果這項功能可以實現,音效檔離線使用的問題就有解了。

下面這個 AudioSprite 滿有趣的,它將多個音效放在一個聲音檔內,然後利用每個音效的時間長度來區分是哪個音效,ex. A+B+C = 10+50+30  ,當我要播放 B 音效時就是播放聲音檔的 11~60 秒,要播放 C 音效時就是播放聲音檔的 61~90 秒。


這樣的話,在 iOS 上較不會有延遲的狀況 ,感覺較流暢。缺點是前置的聲音檔製作要花一點工夫。

1 則留言:

 
雄::gsyan © 2009. Design by Pocket