2013年11月27日 星期三

LimeJS : Audio 無法載入本機的 mp3 檔

在 iOS 上的 Safari 可以利用 HTML5 離線瀏覽的功能,將 .js 或圖片檔案 cache 後,在不連網路時使用,不過卻無法用同樣的方法將音效檔案也 cache 起來,只要是聲音或是影片,播放時都得從網路重新下載,無法離線使用。前幾天突然想到,iFiles 這個 App 可以將檔案儲存,如果將我寫的 HTML5 小遊戲放到 iFiles 裡,就有機會可以不透過網路下載影音檔,直接使用本機裡的檔案。我先拿 2012 年底寫的 HTML5 版「籃球高手」來實驗,因為當初在程式裡就限定網路連線時才會播放聲音檔,必須修改原始碼。改完程式,利用 LimeJS 重新 build 完後,原本可以玩的遊戲居然卡住,連選單都出不來。追了一下錯誤訊息才發現 LimeJS 已經改過了 Audio 的程序,和我當初用的已不同,照它現在的程序,無論是 Chrome 或是 Safari ,預設都無法讀取本機的聲音檔案,因此會造成寫好的程式放到網路上可以正常執行,而放到本機上會卡住的情形。追了一下 LimeJS audio.js 的程式碼,想用舊的方式來使用 Audio ,修改一行即可讓本機可以正常載入聲音檔案。

使用 LimeJS 預設的 audio.js 來載入放在本機的 .mp3 檔案時,以 Chrome 的「JavaScript 控制台」debug,可以看到了底下的錯誤訊息:

類似:

  • XMLHttpRequest cannot load file:///.....xxx.mp3. Cross origin requests are only supported for HTTP. xxx.js:??? Cross origin requests are only
  • XHR error loading file: xxx.mp3 xxx.js:???
  • Uncaught NetworkError: A network error occurred. xxx.js:???

這種訊息之前在研究如何動態的載入 .txt 設定檔時也遇過,主要是瀏覽器的 JavaScript 基於安全因素,不讓我們載入本機的檔案。

應該是 LimeJS 的 audio.js 現在改寫為支援「AudioContext」的關係,如果開啟 LimeJS 目錄裡的「lime/src/audio/audio.js」原始碼,特別注意下圖箭頭所指 (line 35) 的部份:


舊的方式是執行 else (line 40) 以下的程式碼,對我而言,目前想解決「XHR error」的最快方法,就是讓程式跳過「AudioContext」的部份,採用舊程式碼就好。所以將圖中第 35 行的:

if (lime.audio.AudioContext) {

改為:

if (false && lime.audio.AudioContext) {

將 audio.js 儲存好以後,重新 build 程式碼,就和舊版的一樣,收工!


後記 (2013.11.29 更新)

哈!剛剛發現,我好像太粗魯了,其實在開始建立 lime.audio.Audio 物件前,先將「lime.audio.AudioContext」設為「false」就好了,不用去動到預設的程式碼啦!以我自己的程式為例,原來是:
sound = new lime.audio.Audio('assets/basketball_sound.mp3');

在它的前面多加一行,變成:
lime.audio.AudioContext = false;
sound = new lime.audio.Audio('assets/basketball_sound.mp3');

讓它不使用 AudioContext 來建立 audiio 物件即可。





沒有留言:

張貼留言

 
© 2009. Design by Pocket