知道什么时候可以跳到音频文件中的任何一点而不会缓冲/延迟播放

Knowing when I can skip to any point in an audio file without buffering / delay in playback

我正在使用 audio = new Audio() 在我的网页上加载 MP3。但我想知道当设置 audio.currentTime 时,音频可以跳到文件中的任何点 - 接近结尾或任何地方 - 没有任何延迟播放。即我想知道 MP3 何时完整下载。

我可以为此使用音频 object/element,还是必须使用 AudioContext 作为 shown here

每个 AudioElement 都将其缓冲数据公开为 TimeRanges 对象。 TimeRanges 是一个对象,它告诉您已经缓冲了多少个连续部分,也就是范围。它也有 getters return 以秒为单位的每个范围的相应开始和结束。

如果您的 AudioElement 名为 audio,则以下代码片段将记录给定时间点的缓冲时间范围。

const numberOfRanges = audio.buffered.length;

for (let i = 0; i < numberOfRanges; i += 1) {
    console.log(
        audio.buffered.start(i),
        audio.buffered.end(i)
    );
}

如果您想检测缓冲所有数据的时间点,您可以使用类似于此的检查:

const isBufferedCompletely = (audio.buffered.length === 1
        && audio.buffered.start(0) === 0
        && audio.buffered.end(0) === audio.duration);

我使用下面评论中引用的 Gist 来构建示例。以下代码段将定期检查文件是否已缓冲。一旦出现这种情况,它将向控制台记录一条消息。我在 Chrome (v74) 和 Firefox (v66) OS X 上对其进行了测试。请注意,该文件不能同时播放,因为脚本会设置 currentTime音频元素。

const audio = new Audio('http://www.obamadownloads.com/mp3s/charleston-eulogy-speech.mp3');

audio.preload = 'auto';

function detectBuffered(duration) {
    // Stick with the duration once it is known because it might get updated
    // when reaching the end of the file.
    if (duration === undefined && !isNaN(audio.duration)) {
        duration = audio.duration;
    }

    const isBufferedCompletely = (audio.buffered.length === 1
        && audio.buffered.start(0) === 0
        && audio.buffered.end(0) === duration);

    if (isBufferedCompletely) {
        const seconds = Math.round(duration);

        console.log('The complete file is buffered.');
        console.log(`It is about ${ seconds } seconds long.`);
    } else {
        // Move the playhead of the audio element to get the browser to load
        // the complete file.
        if (audio.buffered.length > 0) {
            audio.currentTime = Math.max(0, audio.buffered.end(0) - 1);
        }

        setTimeout(detectBuffered, 100, duration);
    }
}

detectBuffered();