JavaScript:如何获取Audio Context的实际播放位置?(Pizzicato场景)
解决Pizzicato音频播放时获取实际播放位置的问题
核心思路是手动维护播放状态变量,结合context.currentTime和你设置的播放偏移量来计算实际播放位置,具体实现如下:
关键状态变量
需要定义几个变量跟踪播放核心状态:
startOffset:记录每次播放时的起始时间偏移(比如调用start(0,10)时的10秒)playStartTime:记录每次开始播放时的context.currentTime(音频上下文的绝对时间)pauseTime:记录暂停时计算出的实际播放位置isPlaying:标记当前是否处于播放状态
完整代码实现(贴合滑块点击场景)
// 初始化Pizzicato Sound实例 const sound = new Pizzicato.Sound('your-audio-file.mp3', () => { // 音频加载完成后初始化滑块最大值 const slider = document.getElementById('seek-slider'); slider.max = sound.source.buffer.duration * 100; }); // 维护播放状态的变量 let startOffset = 0; let playStartTime = 0; let pauseTime = 0; let isPlaying = false; // 范围滑块点击事件处理(跳转播放位置) document.getElementById('seek-slider').addEventListener('click', (e) => { const slider = e.target; // 将滑块值(0-100)转换为实际音频时间 const targetTime = parseFloat(slider.value) / 100; // 当前正在播放的话先停止 if (isPlaying) { sound.stop(); } // 从目标位置开始播放 sound.start(0, targetTime); // 更新状态变量 startOffset = targetTime; playStartTime = sound.context.currentTime; isPlaying = true; }); // 暂停功能 function pauseAudio() { if (!isPlaying) return; // 计算暂停时的实际播放位置 pauseTime = startOffset + (sound.context.currentTime - playStartTime); sound.stop(); isPlaying = false; // 同步滑块位置到暂停点 document.getElementById('seek-slider').value = pauseTime * 100; } // 获取当前实际播放位置的工具函数 function getCurrentPlayPosition() { if (isPlaying) { // 播放中:起始偏移 + 已播放时长(上下文时间差) return startOffset + (sound.context.currentTime - playStartTime); } else { // 暂停时直接返回记录的暂停位置 return pauseTime; } }
关键逻辑说明
- 滑块跳转播放时,记录目标偏移
startOffset和此时的上下文绝对时间playStartTime,两者结合就能算出播放后的实际进度。 - 暂停时先计算并保存当前实际位置,后续获取位置或继续播放时直接复用该值。
context.currentTime是音频上下文的全局时间,不会随播放偏移改变,所以必须通过手动维护的状态来修正计算。
注意事项
- 必须在音频加载完成的回调内访问
sound.source.buffer.duration,否则会因未加载完成报错。 - 如果需要循环播放,每次循环结束后要更新
startOffset(比如累加音频总时长),保证位置计算准确。
内容的提问来源于stack exchange,提问作者user5405648
相关产品推荐
相关产品推荐

