javascript - 如何用新录制的音频覆盖部分网络音频?

标签 javascript web audio html5-audio web-audio-api

我已成功录制音频,将其存储并重新加载到Audio对象中,以便在浏览器中播放。

但是,我希望能够记录新的音频,并在某个时间偏移量将其“拼接”到原始记录中,从而从该偏移量开始完全替换原始记录的那部分。例如,假设我录制了10秒来自麦克风的音频,随后,我希望用8秒的全新音频“录制”该音频的最后5秒,最后得到一个我可以持久保存的新bufferArray。我已经花了几个小时研究这个问题,但对于如何做仍然很模糊。如果有人有任何建议,我将不胜感激。

我可以找到的最接近的示例包括获取两个缓冲区并尝试将它们连接起来,如this fiddle所示。但是,在将这种提琴与我的代码以及我需要做的事情联系起来时,我遇到了一些困难。某些帖子提到我需要了解采样率,以相同的采样率创建新缓冲区,并将数据从两个缓冲区复制到新缓冲区中。但是,关于这种技术的工作实例很少,我正竭尽全力试图从MDN文档中找出答案。

这是我现在正在使用的代码。

const saveRecordedAudio = (e) => {
  console.log("Audio data available", e.data);
  const reader = new FileReader();
  reader.addEventListener("loadend", function() {
    // reader.result contains the contents of blob as a typed array
    let bufferArray = reader.result;
    // From: https://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string
    let base64String = btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''));
    // persist base64-encoded audio data on filesystem here.
    storeRecordedAudio(base64String); // defined elsewhere and not shown here for brevity's sake
  });
  reader.readAsArrayBuffer(e.data);

  const audioUrl = window.URL.createObjectURL(e.data);
  // Put the recorded audio data into the browser for playback.
  // From: http://stackoverflow.com/questions/33755524/how-to-load-audio-completely-before-playing (first answer)
  const audioObj = new Audio (audioUrl);
  audioObj.load();

};

const recordAudio = () => {
  navigator.getUserMedia = ( navigator.getUserMedia ||
                             navigator.webkitGetUserMedia ||
                             navigator.mozGetUserMedia ||
                             navigator.msGetUserMedia);
  if (navigator.getUserMedia) {
    navigator.getUserMedia (
      { // constraints - only audio needed for this app
        audio: true
      },
      // Success callback
      function(stream) {
        const mediaRecorder = new MediaRecorder(stream);
        mediaRecorder.ondataavailable = audio.saveRecordedAudio;
      }),
      // fail callback
      function(err) {
        console.log('Could not record.');
      }
   );
  }
};


// I've already fetched a previously recorded audio buffer encoded as
// a base64 string, so place it into an Audio object for playback
const setRecordedAudio => (b64string) => {
  const labeledAudio = 'data:video/webm;base64,' + b64String;
  const audioObj = new Audio(labeledAudio);
  audioObj.load();
};

最佳答案

如果我知道您要正确执行的操作,那么可以通过以下方法解决此问题:

1- 我们应该声明一个blob数组并将数据存储在其中:

var chuncks = [];

2- 我们需要知道记录的秒数:

为了限制每个Blob中的毫秒数,我们应该将start(1000)方法与timeslice参数一起使用,
在这种情况下,我们知道每个数据块的长度约为1秒(chunks.length =记录的秒数),并使用ondataavailable事件处理程序填充数据块数据
是我们的 friend :
mediaRecorder.ondataavailable = function( event ) {
    chunks.push( event.data );
}

现在,我们必须处理简单的Arrays而不是Buffer Arrays:-D(在您的示例中,我们应该删除或覆盖最后5个项目,并继续向其中添加blob)

3- 最后,当我们的录音准备就绪时(块数组):

我们应该使用Blob构造函数将它们连接在一起:
new Blob(chunks, {'type' : 'audio/webm;codecs=opus'});

我希望这会有所帮助:-D

关于javascript - 如何用新录制的音频覆盖部分网络音频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53455124/

相关文章:

javascript - 如何检查对象中多个数组的数组长度?

javascript - jquery 中的数据表不实时刷新数据

javascript - 如何使 Web Audio 中的 OscillatorNode 在 0 和 1 之间振荡?

javascript - 在 Rails 中播放上传的音乐

javascript - CasperJS 无法填充谷歌搜索字段

javascript - 使用 history.pushState 后检测浏览器后退按钮

javascript - 在 HTML 中使用三元运算符来决定要实现的类

javascript - 使用 jQuery 和 Javascript 的 for 循环内的函数

html - CSS 和 HTML 的问题 - 边框半径和背景颜色

html - 如何在 iPhone 中播放 HTML 格式的音频?不起作用的示例 :(