Я успешно записываю аудио, сохраняю его и загружаю в 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();
};