修剪或剪切用 mediarecorder JS 录制的音频

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 数组的文档。

更新 2017-02-11

根据 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错误。我在转换过程中遗漏了一个步骤吗?

更新 2017-02-18

Kaiido 指出,chrome存在一个已知的错误,它会阻止我移动音频数据数组。据我所知,这使得目前无法在 chrome 中进行任何类型的音频修剪或剪切(Firefox 音频数组修剪有效,请参阅 Kaiido 的评论小提琴)。

为了实现连续 45 秒追溯记录的最终目标,我现在实例化两个MediaRecorders偏移 45 秒并将它们交换出去。因此,当一个在 45 年代而另一个在 90 年代时,我开始新的录音并摆脱 90 年代MediaRecorder。绝对次优,但​​我目前能找到的最佳解决方案。