Bre*_*son 7 javascript typed-arrays arraybuffer mediarecorder web-audio-api
如何缩短(从前面)一组音频 blob 并仍然具有可播放的音频。
我最终尝试使用 JS MediaRecorder API录制连续 45 秒的音频循环。用户将能够按下按钮,最后 45 秒的音频将被保存。我可以很好地录制、播放和下载单个录音。
当我有一个chunks来自 MediaRecorder的数组称为1000 个 blob 并使用chunks.slice(500, 1000)生成的 blob 数组时,不能用于播放或下载音频。
奇怪的是chunks.slice(0,500)仍然可以正常工作。
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
Run Code Online (Sandbox Code Playgroud)
因为从头到中切片都有效,所以我试着逆向,切片,逆向回到原来的方向。失败的。
我尝试在开始时留下 16 个斑点并删除一些中间的斑点。失败的。
我的预感是 blob 不统一包含数据,需要一些转换为ArrayBuffer或特定的 TypedArray。我已经尝试了许多这样的转换,但仍然没有找到解决方案。任何指导将不胜感激,因为我可以找到任何用于编辑记录的 blob 数组的文档。
根据 Kaiido 的建议连接块,转换为 ArrayBuffer,然后将其传递给 web 音频 api,我尝试了以下操作。
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
Run Code Online (Sandbox Code Playgroud)
以上成功创建了一个与 Blob 大小相同的 ArrayBuffer,但是当我将它传递给decodeAudioData函数时,它会抛出Unable to decode audio data错误。我在转换过程中遗漏了一个步骤吗?
Kaiido 指出,chrome存在一个已知的错误,它会阻止我移动音频数据数组。据我所知,这使得目前无法在 chrome 中进行任何类型的音频修剪或剪切(Firefox 音频数组修剪有效,请参阅 Kaiido 的评论小提琴)。
为了实现连续 45 秒追溯记录的最终目标,我现在实例化两个MediaRecorders偏移 45 秒并将它们交换出去。因此,当一个在 45 年代而另一个在 90 年代时,我开始新的录音并摆脱 90 年代MediaRecorder。绝对次优,但我目前能找到的最佳解决方案。