Проблема:
Во время одноадресной видеоконференции WebRTC я могу успешно транслировать видео с веб-камеры мобильного устройства на ноутбук / настольный компьютер.Я хотел бы записать удаленный поток на стороне ноутбука / рабочего стола.(Настройка заключается в том, что мобильное устройство транслируется на ноутбук / компьютер).
Однако видео поток обычно время от времени зависает.Это не проблема, поскольку сторона «зрителя» наверстает упущенное.Однако запись удаленного потока остановится при первом зависании.
Минимальная и удаленная реализация (локальная запись):
Я могу успешно записать локальный поток из navigator.mediaDevices.getUserMedia()
следующим образом:
const recordedChunks = [];
navigator.mediaDevices.getUserMedia({
video: true,
audio: false
}).then(stream => {
const localVideoElement = document.getElementById('local-video');
localVideoElement.srcObject = stream;
return stream;
}).then(stream => {
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = (event) => {
if(event.data && event.data.size > 0) {
recordedChunks.push(event.data);
}
};
mediaRecorder.start({ mimeType: 'video/webm;codecs=vp9' }, 10);
});
Я могу легко загрузить это следующим образом:
const blob = new Blob(recordedChunks, { type: 'video/webm' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
a.href = url;
a.download = 'test.webm';
a.click();
window.URL.revokeObjectURL(url);
Минимальная и удаленная реализация (удаленная запись):
Используемая мной настройка требует записиУдаленный поток, а не локальный поток, для IOS Safari не поддерживает API MediaRecorder.Я включил выше, чтобы показать, что запись работает на локальной стороне.Реализация записи удаленного потока ничем не отличается, за исключением того, что я вручную добавляю звуковую дорожку с частотой 0 Гц к видео, поскольку в Chrome, как представляется, есть ошибка, из-за которой он не может записывать без звуковой дорожки.
const mediaStream = new MediaStream();
const audioContext = new AudioContext();
const destinationNode = audioContext.createMediaStreamDestination();
const oscillatorNode = audioContext.createOscillator();
oscillatorNode.frequency.setValueAtTime(0, audioContext.currentTime);
oscillatorNode.connect(destinationNode);
const audioTrack = destinationNode.stream.getAudioTracks()[0];
const videoTrack = remoteStream.getVideoTracks()[0]; // Defined somewhere else.
mediaStream.addTrack(videoTrack);
mediaStream.addTrack(audioTrack);
И затем я выполняю те же самые операции, что и в примере с локальным потоком, для записи переменной mediaStream
.
Как уже упоминалось, в первой точке, где зависает удаленный поток (возможно, из-за задержки в сети)), удаленная запись прекращается, так что при загрузке продолжительность файла .webm
, преобразованного в .mp4
через ffmpeg
, составляет только то время, когда произошло первое зависание.
Попытки смягчить:
Одна попытка решить эту проблему, которую я пробовал, состоит в том, чтобы вместо записи удаленного потока, который достигается при обратном вызове для события ontrack
из WebRTC, я используювместо этого поток видео с удаленного элемента видео через remoteVideoElement.captureStream()
.Это не работает, чтобы решить проблему.
Любая помощь будет принята с благодарностью.Спасибо.