WebRTC изменение / перемещение видеоэлемента без остановки потока
Играя с WebRTC в Chrome, я замечаю, что долговечность этих потоков все еще несколько шаткая. Мне нужно создать видеопоток до того, как элемент, отображающий его, будет показан (технически мне изначально нужна только аудиодорожка, но пересмотр без replaceTrack() кажется проблемой само по себе, поэтому сейчас я включаю оба сразу.).
Затем элемент динамически отображается с помощью JavaScript и должен начать получать видео WebRTC. Проблема в том, что на момент создания WebRTC этот элемент видео, где я хочу показать его, еще не существует. Я не вижу способа указать WebRTC изменить элемент видео, отображаемый после запуска потока, это возможно? Я в основном играл с SimpleWebRTC, но я открыт для непосредственного использования WebRTC - просматривая документы, я также не смог найти способ сделать это с помощью простого WebRTC. Я также попытался переместить оригинальный элемент видео в новый элемент, но это приводит к прерыванию / остановке видеопотока:
newElement.appendChild(originalWebRTCVideoTag);
Если не считать уничтожение всего потока и перезапуск, какие у меня варианты?
ОБНОВЛЕНИЕ:
Для обоих подходов videoTag - это общий тег видео DOM, а webrtc - это экземпляр WebRTC
объект с рабочим соединением, установленным через SimpleWebRTC (simpleWebRtc.webrtc, который SimpleWebRTC оборачивает). Я собираю JSFiddle прямо сейчас для тех, кто хочет увидеть реальный код, но этой информации должно быть достаточно, чтобы воспроизвести это.
// this doesn't seem to be working in stackru, probably because it rejects video camera capture
var simplertc = new SimpleWebRTC({
localVideoEl: 'webrtc-local',
remoteVideosEl: 'webrtc-remote',
media: {"audio": true, "video": {
"optional": [{"minWidth": "640"}, {"minHeight": "480"}], "mandatory": {}
}},
autoRequestMedia: true
});
var webrtc = simplertc.webrtc;
// this portion is overly simplified, in this case there is no point
// in creating this dynamically, in the app I'm working on this element
// is generated much later
$('#dynamic').appendTo('<video id="dynamic-video"></video>');
var videoTag = $('#dynamic-video')[0];
simplertc.on('readyToCall', function() {
simplertc.joinRoom('my-room-875385864'); // random name
// by this time the local video should be ready, we don't need remote ones for our test
// test case 1 (replace with logic from test case 2 if needed)
videoTag.srcObject = webrtc.localStreams[0];
// end test case
});
video {
border: 1px solid red;
width: 200px;
}
/* overlap with original video is intentional to show hardware acceleration effect */
#dynamic {
position: absolute;
border: 1px solid black;
width: 200px;
height: 200px;
left: 100px;
top:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://simplewebrtc.com/latest-v2.js"></script>
<div id='webrtc'>
<video id='webrtc-local'></video>
<div id='webrtc-remote'></div>
</div>
<div id='dynamic'>
</div>
Подход 1, случайно наткнулся на это при попытке сближения 2
Попробовал следующее, работает, но гораздо медленнее, чем хотелось бы, около 5 FPS:
// note that I can just as easily use remote streams here
videoTag.srcObject = webrtc.localStreams[0]
По иронии судьбы, пока я больше возился с этим подходом, я случайно перекрыл видеообласти элемента webRTC и сгенерированного (videoTag), и хотя webRTC находится на заднем плане, этот угол videoTag, где он перекрывается, работает в реальном времени, в отличие от остальная часть элемента, который продолжает работать на 3-5 FPS. Это наводит меня на мысль, что проблема здесь в аппаратном ускорении. Можно ли как-то включить его для videoTag?
Подход 2
var media = new MediaSource();
videoTag.src = URL.createObjectURL(media);
// guessing mimetype from a few WebRTC tutorials I stumbled upon
var srcBuf = media.addSourceBuffer(‘video/webm;codecs=”vp8, vorbis”’);
// need to convert webrtc.localStreams[0] or its video track to a buffer somehow???
srcBuf.appendBuffer(/* buffer */);
ДАЛЬНЕЙШИЕ ИССЛЕДОВАНИЯ
Это может быть ошибкой в Chrome, хакерский обходной путь, который, кажется, работает, состоит в том, чтобы удостовериться, что вновь сгенерированные элементы видео полностью перекрываются исходным элементом видео (даже если исходный элемент видео настроен для рендеринга на фоне позади всех других элементов). (и за непрозрачным фоном.) Это похоже на ускорение аппаратного ускорения.
1 ответ
Ты можешь использовать MediaSource
, sourceopen
событие, .addSourceBuffer()
, .appendBuffer()
, Посмотрите потоковое аудио в HTML5: точно измерьте задержку?, Невозможно передавать видео через веб-сокет в Firefox