Как я могу объединить два аудиофайла - JavaScript?

У меня есть два аудиофайла из RecordRTC как локального, так и удаленного потоков. Теперь я хочу объединить два файла в один файл и загрузить его на сервер через AJAX.

например (audio1.webm) и (audio2.webm).

mediaRecorder.stopRecording(function() {
    var blob = mediaRecorder.getBlob();
    var fileName = getFileName('webm');

    var fileObject = new File([blob], fileName, {
        type: 'audio/webm'
    });

    var formData = new FormData();
        formData.append('blob', fileObject);
        formData.append('filename', fileObject.name);

    $.ajax({
        url: '{{ url('/') }}/save-audio',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        success: function(response) {
            console.log(response);
        }
    });
});

Заранее спасибо.

ОБНОВИТЬ:

Я сделал это вместо recorder.addStreams, и все же я могу получить запись.

var remoteVideos = $('#remoteVideos video');
var el = [];

$.each($('#remoteVideos video'), function(index, val) {
     el[index] = val.srcObject;
});
el.push(stream);
multiMediaRecorder = new MultiStreamRecorder(el);

person Jin    schedule 14.02.2020    source источник
comment
когда вы говорите объединить, вы имеете в виду объединение двух аудиофайлов или объединение их по-другому?   -  person dontcallmedom    schedule 14.02.2020
comment
Спасибо за ваш ответ. Я хочу их объединить, потому что аудиофайлы содержат разговор. например, audio1 задает вопрос, а audio2 дает ответ.   -  person Jin    schedule 14.02.2020
comment
Я попробовал ffmpeg только на своем локальном компьютере, но как мне настроить его на реальном сервере?   -  person Jin    schedule 17.02.2020
comment
К вашему сведению, аналогичный вопрос здесь, где ответы принимают другой подход: mediarecorder-api/62336773" title="как объединить несколько звуковых дорожек в одну для mediarecorder api"> stackoverflow.com/questions/55165335/   -  person Adam Marsh    schedule 03.01.2021


Ответы (2)


Вы можете использовать аналогичную библиотеку: MediaStreamRecorder. Затем используйте MultiStreamRecorder и передайте два потока, как показано ниже:

recorder = new MultiStreamRecorder([localStream, remoteStream]);

Вы получите localStream из getUserMedia и remoteStream из прослушивателя событий onaddstream.

Вы можете просто передать звуковые дорожки в массиве. Остальное как есть. FFmpeg и объединение файлов не требуется.

person ishan shah    schedule 17.02.2020
comment
Спасибо @ishan, но я немного не понимаю, как определить, является ли это локальным потоком или удаленным потоком? - person Jin; 18.02.2020
comment
Вы можете мне помочь, сэр? Я застрял на этой проблеме. Я новичок в javascript, а также в этой библиотеке. - person Jin; 18.02.2020
comment
Поток, который вы получаете в методе getUserMedia, — это ваш локальный поток, а тот, который вы получаете в прослушивателе onaddstream, — это ваш удаленный поток. - person ishan shah; 18.02.2020
comment
Можно ли использовать этот код для получения remoteStreams $('#remoteVideos video')[0]. Максимум 8 удаленных потоков. - person Jin; 18.02.2020
comment
О, мой плохой. Каков наилучший подход для этого? используя addStreams? вы можете дать пример кода. - person Jin; 18.02.2020

Я получил это сейчас, сделав это, как показано ниже;

function onMediaSuccess(localStream) {

            var remoteVideos = $('#remoteVideos video')[0];
            multiMediaRecorder = new MultiStreamRecorder([localStream, remoteVideos.srcObject]);
            multiMediaRecorder.ondataavailable = function (blob) {
                // POST/PUT "Blob" using FormData/XHR2
                var blobURL = URL.createObjectURL(blob);
                console.log(blobURL);
            };
            multiMediaRecorder.start();
    }

Но теперь есть другая проблема, ondataavailable вызывается дважды, но первое видео воспроизводится и работает правильно, а второе видео воспроизводится, но (менее одной секунды) Я думаю, что оно может быть повреждено.

Ваше здоровье!

person Jin    schedule 18.02.2020
comment
Вместо этого используйте переменную. Объявите массив BLOB-объектов и вставляйте его при получении данных. Например, recorder.ondataavailable = blob => RecordedBlobs.push(blob); - person ishan shah; 18.02.2020
comment
Хорошо, спасибо.. тогда я хочу загрузить его на свой сервер через ajax. Можно ли вызывать его внутри функции ondataavailable? - person Jin; 18.02.2020
comment
Да, все в порядке. Пожалуйста, примите мой ответ, если он помог. - person ishan shah; 18.02.2020
comment
Привет @ishanshah, после того, как я сохранил блоб на сервере, он воспроизводим, но когда я обновляю видеовызов, он больше не работает, он говорит Your file was not found (It may have been moved or deleted) - person Jin; 19.02.2020