HTMLMediaElement.durationはメディアが読み込まれるまでNaNなので、awaitかなにかで待つ必要がある
2024/07/16
Issue
「音声の再生時間(長さ)を超えるまで繰り返し」という処理を書こうとした
そしたら audioUnit.element.duration
が NaN
だって言われてしまい失敗
main.js const audioUnit = new DJ_AudioUnit(chartDB.music); // DJ_AudioUnit.elementがHTMLAudioElementになってる。chartDB.musicは音声ファイルのURL
/* ==== 譜面オブジェクトを用意する ==== */
// 1. 譜面データを取得
const chart = /*(略)*/;
{
// (略)
let currentTime = chart.offset;
for (let i = 1; currentTime <= audioUnit.element.duration; i++) {
// (略)
}
// (略)
Solution
以下のコードを const audioUnit = ……
の次の行に追加
なにもしないとファイルの読み込みを待たずに次の行にいってしまうので、 await
で待たせる
読み込み完了していつでも再生できるよ!になったら canplaythrough
イベントが発火するので、これを待てばいい
durationchange
イベントでもいい気がするが、自信がいまひとつだしどうせあとで再生可能になるまで待たなきゃいけないので canplaythrough
にした
たまたまasync functionだったので安易に await
で待ったが、そうでなければ Promise.then
とかで待つか oncanplaythrough
に続きを書くか……
main.js // audioUnit.elementの読み込みが完了するまで待機
await new Promise(resolve => {
audioUnit.element.addEventListener("canplaythrough", resolve, { once: true });
});