Как показать дорожки видеопотока из двух разных потоков в одном элементе HTMLMediaElement (из потока камеры и потока WebGL)

Мне нужно показать видео с камеры пользователя и виртуальные объекты, созданные с помощью WebGL, на веб-странице в одном элементе html, возможно, либо <canvas>, либо <video>.

Я могу успешно получить пользовательское видео, это поток, с медиаустройств навигатора и показать его в элементе <video>.

Я могу успешно создавать виртуальные визуальные объекты с помощью WebGL и отображать их в элементе <canvas>, используя другой пример кода здесь (из MDN).

Мне нужно смешать их в одном элементе html. Как я могу этого добиться.

Мои дальнейшие исследования показывают, что существует captureStream() метод HTMLMediaElement интерфейса. И <video>, и canvas имеют этот метод. Я могу захватить поток из таких элементов и использовать его для чего-то другого, например присоединения к другому элементу html (но, возможно, не к элементу холста) или одноранговому соединению WebRTC как источник, записывая его. Но это перезаписывает предыдущий поток.

Затем я обнаружил, что поток с именем MediaStream содержит дорожки внутри них, такие как видеодорожки, аудиодорожки даже текстовые дорожки. И еще можно добавить addTrack методом MediaStream, а получить их можно getTracks методом. Я добавил видеодорожку из потока моего <canvas> элемента в поток <video> элементов, однако я могу просматривать исходную видеодорожку только из пользовательского мультимедиа в элементе <video>.

Чего мне не хватает, чтобы добиться этого?

<html>
  <body>
    getting video stream from camera into screen
    <video autoplay></video>

    getting virtual objects into screen
    <canvas id="glcanvas" width="640" height="480"></canvas>
  </body>
  // webgl codes that draws a rotating colored cube on html canvas webgl context
  <script src="gl-matrix.js"></script>
  <script src="webgl-demo.js"></script>

  <script>
    // getting video stream from camera into screen
    const video = document.querySelector("video"); 

    navigator.mediaDevices.getUserMedia({video: true})
      .then(stream => {
        let canv = document.querySelector("#glcanvas");
        let canvstrm = canv.captureStream();
        // get track from the canvas stream and add to the user media stream
        let canvstrmtrack = canvstrm.getTracks()[0]
        stream.addTrack(canvstrmtrack);
        video.srcObject = stream;
    })
  </script>


</html>

Полная суть


person sçuçu    schedule 11.05.2019    source источник
comment
Что вы имеете в виду, смешав их в одном элементе html? Как бы это выглядело?   -  person jib    schedule 12.05.2019
comment
Их будет видно вместе. Например, в то время как видео показывает человека на экране, виртуальный куб будет находиться перед человеком в видео.   -  person sçuçu    schedule 12.05.2019
comment
Ах, вы хотите, чтобы графика накладывалась на видео, например. черный как прозрачный? Элементы видео могут одновременно воспроизводить только один источник видео. Если вы никуда не отправляете результаты, вы можете расположить холст с прозрачностью поверх видеоэлемента с помощью CSS.   -  person jib    schedule 12.05.2019
comment
Видеоэлементы могут одновременно воспроизводить только один источник, но может ли этот источник, поток иметь более одной видеодорожки, что кажется возможным? Разве это не должно накладываться тогда. Если да, то почему я не могу видеть их обоих? Добавление трека делается по-другому или его функция не такая, как я думаю?   -  person sçuçu    schedule 12.05.2019


Ответы (1)


Элемент видео может одновременно воспроизводить только одну видеодорожку.

Поддержка этого содержится в спецификации MediaCapture:

Поскольку порядок в MediaStream в набор дорожек не определен, никаких требований к тому, как AudioTrackList и VideoTrackList упорядочен

И в HTML< /а>:

Выбран либо ноль, либо одна видеодорожка; выбор новой дорожки при выбранной предыдущей приведет к отмене выбора предыдущей.

Похоже, вы ожидали, что графика будет накладываться на видео, например. черный как прозрачный.

На данный момент на веб-платформе нет хороших инструментов для создания видео. Практически единственный вариант — многократно рисовать кадры из видеоэлемента на холсте и использовать canvas.captureStream, но это ресурсоемко и медленно.

Если вы просто делаете это для воспроизведения (не записываете и не передаете результат), то вы можете добиться этого эффекта намного дешевле, расположив холст с прозрачностью поверх элемента видео с помощью CSS. Этот подход также позволяет избежать ограничений по происхождению.

person jib    schedule 12.05.2019
comment
Да, я ожидал, что наложу их в один элемент html. Запись пока не нужна, как и передача. Даже передача может быть выполнена с ним, как вы сказали, путем умной передачи наложенных данных css и т. Д. Я хотел бы показать виртуальные изображения в том виде, в котором они (или действительно) находятся в местах на видео, сохраняя фиксированное сочетание угла компаса, местоположения и ориентация гироскопа. - person sçuçu; 12.05.2019