優化 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()創建就好。

| 軟體開發 | 網站建置 | 網頁系統 | 資料庫網站 |

| 客製化網站 (報名系統、投票系統、掛號系統...) |

| 前後端技術合作 |

歡迎與我們聯繫:jessica@penueling.com

加入Line立即聊聊:@539mjyid

0
0 回復

發表評論

Want to join the discussion?
Feel free to contribute!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。