我目前正在尝试弄清楚如何使用网络音频 API 播放分块音频,一切都正常。但是,大多数块之间的转换并不像我希望的那样顺利,有一个非常非常短暂的时刻大多数人之间保持沉默。
我当前的加载和播放代码:
const response = await fetch(`${this.src}`)
const reader = response.body.getReader()
let timestamptowaituntil = 0
let tolog = []
let tolog2 = []
while (true) {
const { done, value } = await reader.read()
if (done) {
console.log(tolog)
console.log(tolog2)
console.log(this.ctx)
break
} else {
let audiodata = await this.ctx.decodeAudioData(value.buffer)
let source = this.ctx.createBufferSource()
source.buffer = audiodata
source.connect(this.ctx.destination)
source.start(timestamptowaituntil, 0, audiodata.duration)
timestamptowaituntil +=audiodata.duration
tolog.push(audiodata)
tolog2.push(source)
}
}
我怎样才能消除这些短暂的沉默(或重叠)时刻?
编辑:到目前为止我已经尝试过以下方法
- 减少了几毫秒的等待时间。
- 删除 AudioContext 的延迟属性中的时间量。
- 创建一个函数来使用其比特率获取 UInt8Array 表单数据的播放长度(这确实给我带来了与 audioBuffer 的 .duration 属性略有不同的结果,但仍然存在微小的差距)
在尝试了很多不同的方法之后,我终于有了一个最终解决问题的想法。
我的新想法是简单地在第一个块到达时播放它,同时收集尽可能多的块,每当收集一个块时,它就会与前一个块链接起来以形成一个更大的块(这种方式也使其可以在 Firefox 中工作)要求块具有用于解码的标头)。第一个块的播放在 .duration 属性声明其结束之前 0.5-1 秒停止,这样可以避免检测长度时出现任何异常。同时,播放下一个块。
我为此添加到代码中的一些内容如下:
连接两个块的函数:
const concat = (arrayOne, arrayTwo) => {
let mergedArray = new Uint8Array(arrayOne.length + arrayTwo.length)
mergedArray.set([...arrayOne, ...arrayTwo])
return mergedArray
}
计时时的额外偏移:
source.start(timestamptowaituntil, 0, audiodata.duration - .75)
timestamptowaituntil += (audiodata.duration - .75 + this.ctx.currentTime)
这加上一些更小的编辑给我带来了一个解决方案,使块交换不可能被听到(时不时地是当CPU过载并且计时变慢时)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)