優化 javascript 連續播放 mp3 音頻 audio 在 ios 上的延遲問題
這篇我光是文章標題就想好久,到底要怎樣一句話就包含所有關鍵字然後說明我到底遇到什麼問題(乾笑
是這樣的,因為最近接一個網頁遊戲的案子,如果有贏的話就要連續播放「叮叮叮叮」的聲音來後開始得分跑數字。
業主給我的 mp3 檔案只有「叮」一聲,所以我要依照玩家贏多少分,「叮」這個聲音就要看我得幾分,就跑幾次,也可以每十分跑一次拉,不然跑太久,反正這是細節。
原本我使用的是以下這種方式:
const ScoreAudioSrc = require("@G/assets/audios/Score.mp3");
const ScoreAudio = new Audio(ScoreAudioSrc);
//...
let scoreInterval;
const handleScoreInterval = () => {
ScoreAudio.cloneNode(true).play();
}
//...
// 按下按鈕的時候 button click
const handleGetScore = () => {
scoreInterval = window.setInterval(handleScoreInterval, 90);
}
// 然後得完分記得要clearInterval
clearInterval(scoreInterval)
這樣在電腦跑是可以很正常的,但是在 ios 手機就是一場災難…
上網查了一下,好像是因為電腦可以載入一次音頻就一直播放,但是ios才不鳥你,他一定要在click事件觸發才可以播放,然後又因為每次都要載入,所以音頻都會延遲,你都得完分了,才會突然聽到「叮叮叮」到底在叮沙毀。
於是今天早晨我在位子上要開始修復這個問題時,禱告了大概30秒,這問題不解決我不能結案啊QQ 離假日只剩三天,一定要趕快弄好。
禱告完之後我就開始重新用別的關鍵字搜尋這個問題,神奇的是!中午前我就找到解法了!!
以下是解決方案:
//首先一樣要先把你的檔案引入
const ScoreAudioSrc = require("@G/assets/audios/Score.mp3");
// 然後在全域的地方宣告 AudioContext
const AudioContext = window.AudioContext || window.webkitAudioContext;
let audioCtx;
// 接著我們在點擊 button click 的時候創建 AudioContext 實例並建立音頻然後播放
const handleGetScore = () => {
audioCtx = new AudioContext();
audioCtx.resume();
scoreInterval = window.setInterval(handleScoreInterval, 90);
}
// 建立音頻&播放
let scoreInterval;
const handleScoreInterval = () => {
fetch(ScoreAudioSrc)
.then(response => response.arrayBuffer())
.then(arrayBuffer =>
audioCtx.decodeAudioData(
arrayBuffer,
function(buffer) {
const source = audioCtx.createBufferSource();
source.buffer = buffer;
source.connect(audioCtx.destination);
source.start();
},
function(e) {
console.log("Error with decoding audio data" + e.err);
},
),
);
}
// 然後得完分記得要clearInterval
clearInterval(scoreInterval)
因為我有很多地方要連續播放音頻(像是發撲克牌的時候也要一次發三張,所以跑三次發牌音效),所以我的audioCtx
變數就放在全域,要用的時候在從 click 那個 funciton 去new AudioContext()
創建就好。
0
發表評論
想要加入討論嗎?請盡情發表您的想法!