HTMLMediaElement.durationはメディアが読み込まれるまでNaNなので、awaitかなにかで待つ必要がある
2024/07/16
Issue
「音声の再生時間(長さ)を超えるまで繰り返し」という処理を書こうとした
そしたらaudioUnit.element.durationがNaNだって言われてしまい失敗
code: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に続きを書くか……
code:main.js
// audioUnit.elementの読み込みが完了するまで待機
await new Promise(resolve => {
audioUnit.element.addEventListener("canplaythrough", resolve, { once: true });
});