HTML5 Видеопоток из веб-сокета через MediaSource и MediaSourceBuffer - PullRequest
0 голосов
/ 27 апреля 2020

Я пытаюсь воспроизвести видео из websocket

<video id="output" width="320" height="240" autoplay></video>

<script>
    function sockets(buffer) {
        const socket = new WebSocket('wss://localhost:5002/ws')

        socket.onmessage = async function (event) {
            // event.data is a blob
            buffer.appendBuffer(new Uint8Array(event.data))
        }
    }

    let ms = new MediaSource()
    let output = document.getElementById('output')
    output.src = URL.createObjectURL(ms)
    ms.onsourceopen = () => {
        let buffer = ms.addSourceBuffer('video/webm; codecs="vorbis,vp8"')
        sockets(buffer)
    }
</script>

Я получаю фрагменты MediaRecorder здесь в виде BLOB-объектов и пытаюсь последовательно воспроизводить их с помощью MediaSource API. Никаких ошибок и ничего не происходит. Здесь что-то в корне не так?

Я пытался:

  • Для использования разных кодеков
  • Воспроизведение с режимами источника медиа, например, последовательность / сегменты
  • Я также пробовал разные способы, где вы не используете MediaSource API, но столкнулись с другими проблемами, и MediaSource, похоже, является лучшим подходом в моем случае.

ОБНОВЛЕНИЕ: так создается видео:

let options = { mimeType: 'video/webm;codecs=vp8' }
let stream = await navigator.mediaDevices.getUserMedia({ video: true })
mediaRecorder = new MediaRecorder(stream, options)
mediaRecorder.ondataavailable = event => {
    if (event.data && event.data.size > 0) {
        send(event.data)
    }
}

1 Ответ

0 голосов
/ 28 апреля 2020

Фундаментальная проблема здесь в том, что вы не можете передавать данные, поступающие из MediaRecorder, и ожидать, что другой конец их воспроизведет; это не полное видео. Он будет работать только в том случае, если принимающая сторона сможет получить байтов инициализации , что, я сомневаюсь, будет работать в реальном сценарии.

Что вы можете сделать, это создать интервал, который будет запускать / останавливать MediaRecorder, например, каждую 1 секунду, чтобы создать 1-секундные фрагменты видео, которые вы можете передавать по проводам (лучше всего я знаю и проверял это веб-сокеты )

Я настоятельно рекомендую не использовать MediaRecorder, если вы делаете потоковое видео в реальном времени, которое не было указано в вашем сообщении, но если да, лучше создать холст для копирования потока и делать некоторые вещи requestAnimationFrame, которые могут захватывать ваш видеопоток во что-то, что вы можете передавать.

Взгляните на эту демонстрацию для справки: https://github.com/cyberquarks/quarkus-websockets-streamer/blob/master/src/main/resources/META-INF/resources/index.html

MediaRecorder в моем опыте реакция задерживается, что обычно добавляет довольно большую задержку в видео, не говоря уже о задержке, которую сокет также вводит.

Как правило, другие разработчики рекомендуют использовать маршрут WebRT C, однако, исходя из моего опыта, WebRT C обычно не работает быстрее.

...