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 stackoverflow, 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, хакерский обходной путь, который, кажется, работает, заключается в том, чтобы убедиться, что вновь сгенерированные видеоэлементы полностью перекрываются исходным видеоэлементом (даже если исходный видеоэлемент настроен для рендеринга на фоне за всеми другими элементами. (и за непрозрачным фоном) Это похоже на аппаратное ускорение.


person Alexander Tsepkov    schedule 11.02.2017    source источник
comment
В chrome, chromium вы должны иметь возможность включить аппаратное ускорение на Settings   -  person guest271314    schedule 12.02.2017
comment
Он уже включен, эта проблема относится к этому элементу, а не к другим тегам видео.   -  person Alexander Tsepkov    schedule 12.02.2017
comment
Вы что-то делаете не так. Поток, удаленный или другой, существует полностью независимо от того, какие видеоэлементы могут его воспроизводить или воспроизводят ли они его вообще. Это не имеет ничего общего с WebRTC. См. Этот пример.   -  person jib    schedule 12.02.2017
comment
srcObject - это свойство DOM, а не свойство jQuery, используйте videoTag[0].srcObject. Все еще не уверены, в чем проблема?   -  person guest271314    schedule 12.02.2017
comment
@ guest271314 спасибо, это была опечатка, я знаю, что это не имеет ничего общего с jQuery. Я забыл [0] при вводе примера выше, в исходном коде он есть.   -  person Alexander Tsepkov    schedule 12.02.2017
comment
@jib Я не говорю, что это как-то связано с WebRTC. Первоначальный вопрос касался WebRTC, потому что именно отсюда я получаю поток. Как только поток будет назначен srcObject, я ожидаю, что он будет иметь ту же производительность, что и исходный поток. Это не так, за исключением области, которая перекрывается с исходным видео (независимо от содержимого этого видео и независимо от того, где оно находится в стеке z-индекса). Для меня это определенно звучит как ошибка аппаратного ускорения.   -  person Alexander Tsepkov    schedule 12.02.2017


Ответы (1)


Вы можете использовать MediaSource, sourceopen событие, .addSourceBuffer(), .appendBuffer(). См. Потоковое аудио HTML5: точно измерить задержку?, Невозможно передавать потоковое видео через веб-сокет в Firefox

person guest271314    schedule 11.02.2017
comment
Спасибо, я прошел большую часть пути, используя онлайн-руководства, объясняющие методы, которые вы упоминаете (также проверил ваш). Сейчас моя единственная проблема - это преобразование MediaStream из webRTC в буфер, который может использовать MediaSource.appendBuffer (), я не вижу способа, смотрел видео MediaStreamTrack внутри MediaStream, похоже, он тоже не раскрывает буфер. Я предполагаю, что буфер (который является ArrayBuffer на основе спецификации) является базовым массивом пикселей для потока? - person Alexander Tsepkov; 12.02.2017
comment
Можете ли вы включить javascript, который вы пробовали в Вопросе? - person guest271314; 12.02.2017
comment
Хорошо, только что придумал альтернативный способ, но он медленный, как патока, поэтому, если буферный подход более эффективен, я бы хотел его понять. Мой текущий подход не использует .appendBuffer () или .addSourceBuffer (). Вместо этого я сделал это: video.srcObject = webrtc.localStreams[0]; - person Alexander Tsepkov; 12.02.2017
comment
Что вы имеете в виду под медленным? - person guest271314; 12.02.2017
comment
Примерно 3-5 FPS, тогда как исходный видеоэлемент WebRTC, кажется, работает в реальном времени. Кроме того, обновление вопроса с частями вашего подхода, который я пробовал до сих пор (как уже упоминалось, я еще не смог найти рабочее решение с использованием вашего подхода, поэтому он не будет рабочим кодом). - person Alexander Tsepkov; 12.02.2017
comment
webrtc.localStreams[0] - это MediaStream, да? Можете ли вы создать plnkr.co подхода plnkr, используя video.srcObject? - person guest271314; 12.02.2017
comment
Да, это именно то, что я сделал в своем третьем комментарии выше, который работает медленно. Кроме того, см. Обновленное описание: я случайно перекрыл две области видео, и в перекрывающемся углу пропала медлительность, даже несмотря на то, что медленное видео находится поверх другого элемента. Это заставляет меня думать, что проблема в том, что видеоэлемент webrtc каким-то образом подключается к аппаратному ускорению, тогда как мой - нет. Мысли? - person Alexander Tsepkov; 12.02.2017
comment
Не знаете, как обеспечить правильную оценку, не имея возможности воспроизвести javascript, который вы сейчас пытаетесь. - person guest271314; 12.02.2017