所需知识
如何(从前面)缩短音频 blob 数组并仍然具有可播放的音频。
Goal
我最终尝试使用 JS 录制连续 45 秒的音频循环媒体记录器 https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorderAPI。用户只需按一下按钮,最后 45 秒的音频就会被保存。我可以很好地录制、播放和下载单个录音。
Issue
当我有一个名为chunks
比如说来自 MediaRecorder 的 1000 个 blob 并使用chunks.slice(500, 1000)
生成的 blob 数组不能用于播放或下载音频。
说来也怪chunks.slice(0,500)
仍然工作正常。
Code
let chunks = [];
navigator.mediaDevices.getUserMedia({ audio: true })
.then((stream) => {
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = (e) => chunks.push(e.data);
}
// At some later time, attempt to trim
const trimmedAudio = chunks.slice(500, 1000)
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
const audioURL = URL.createObjectURL(blob);
// audio is an audio DOM element
audio.src = audioURL;
// At this point the audio won't play
尝试过的解决方案
因为从头到中间切片是可行的,所以我尝试了反转、切片、再反转回原来的方向。失败的。
我尝试在开始时留下 16 个斑点,并删除中间的一些。失败的。
Hunch
我的预感是 blob 并不统一包含数据,需要进行一些转换数组缓冲区 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer或特定的 TypedArray。我已经尝试了许多这样的转换,但仍然没有找到解决方案。任何指导将不胜感激,因为我可以找到任何用于编辑记录的 blob 数组的文档。
更新2017-02-11
根据 Kaiido 关于连接块、转换为 ArrayBuffer,然后将其传递给网络音频 api 的建议,我尝试了以下操作。
const blob = new Blob(chunksFromMediaRecorder, { 'type' : 'audio/ogg codecs=opus' })
// blob is Blob size: 32714, type: "audio/ogg codecs=opus"}
function playFromBlob(blob) {
const aCtx = new (window.AudioContext || window.webkitAudioContext)()
const source = aCtx.createBufferSource()
const fileReader = new FileReader()
let arrayBuffer
fileReader.onload = function() {
arrayBuffer = this.result
console.log('arrayBuffer', arrayBuffer) // ArrayBuffer {} with byte length 32714
aCtx.decodeAudioData(arrayBuffer) // throws: Uncaught (in promise) DOMException: Unable to decode audio data
.then(decodedData => {
// use the decoded data here
source.buffer = decodedData
source.connect(audioCtx.destination)
})
}
fileReader.readAsArrayBuffer(blob);
}
上面成功创建了一个与 Blob 大小相同的 ArrayBuffer,但是当我将它传递给decodeAudioData
函数,它会抛出Unable to decode audio data
错误。我在转换过程中是否遗漏了某个步骤?
更新2017-02-18
Kaiido指出,有一个已知的bug https://bugs.chromium.org/p/chromium/issues/detail?id=642012使用 chrome 会阻止我移动音频数据数组。据我所知,这可以进行任何类型的音频修剪或剪切目前不可能在 chrome 中(Firefox 音频数组修剪有效,请参阅 Kaiido 的评论小提琴)。
为了实现我连续45秒回溯录制的最终目标,我现在实例化两个MediaRecorders
偏移 45s 并将它们交换出来。因此,当一个是 45 年代,另一个是 90 年代时,我开始新的录音并摆脱 90 年代MediaRecorder
。绝对不是最理想的,但这是我目前能找到的最佳解决方案。