Как я могу перезаписать часть веб-аудио новым записанным аудио? - PullRequest
0 голосов
/ 24 ноября 2018

Я успешно записываю аудио, сохраняю его и загружаю в Audio объект для воспроизведения в браузере.

Однако я хотел бы иметь возможность записывать новое аудио и «склеивать» его в исходную запись с определенным временным сдвигом, полностью заменяя эту часть исходной записи далее из этого смещения.Например, предположим, что я записал 10 секунд звука с микрофона, а затем я хотел «записать» последние 5 секунд этого звука с 8 секундами совершенно нового звука, в результате чего появился новый буферный массив, который я мог сохранить.Я потратил несколько часов на изучение этого вопроса и до сих пор не знаю, как это сделать.Если у кого-то есть какие-либо предложения, я был бы признателен.

Самые близкие примеры, которые я мог найти, включали получение двух буферов и попытку объединить их, как в этой скрипке .Тем не менее, у меня есть некоторые трудности, связанные с этой скрипкой в ​​моем коде и что мне нужно сделать.В некоторых публикациях упоминается, что мне нужно знать частоту дискретизации, создавать новые буферы с той же частотой дискретизации и копировать данные из двух буферов в новый буфер.Но есть несколько драгоценных рабочих примеров по этой технике, и я сильно ломаю голову, пытаясь понять это только из документов 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: /7020731/arraybuffer-dlya-base64-kodirovannoi-stroki
    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 Ответ

0 голосов
/ 24 ноября 2018

Если я правильно понимаю, что вы пытаетесь сделать, вот мой способ решения этой проблемы:

1- Мы должны объявить массив BLOB-объектов и хранить в нем данные:

var chuncks = [];

2- Нам нужно знать количество записанных секунд:

Мы должны использовать метод start (1000) сПараметр timeslice, чтобы ограничить количество миллисекунд в каждом двоичном объекте, в этом случае мы знаем, что каждый фрагмент данных имеет длину приблизительно 1 секунду (chunks.length = количество записанных секунд). И заполните массив chunks с помощьюdata, ondataavailable Обработчик событий - наш друг:

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

...