Как я могу воспроизвести фрагментированный видеофайл (прикрепленный к вопросу) в видеоэлементе HTML5 с MSE? - PullRequest
0 голосов
/ 21 февраля 2020

Давайте рассмотрим этот видеофайл (A) и этот файл (B).

Я хочу воспроизвести оба файла в браузере с HTML5 и MSE. Технически я хочу обслуживать этот файл по частям, и JavaScript будет подавать тег видео через MSE:

<!DOCTYPE html>
<html>
    <head>
        <title>WebSocket and MSE demo</title>
    </head>

    <body>
        <video id="livestream" width="640" height="480" autoplay />
    </body>

    <script>
            //var verbose = false;
            var verbose = true;

            // set mimetype and codec
            var mimeType = "video/mp4";
            var codecPars = mimeType;

            var streamingStarted = false; // is the sourceBuffer updateend callback active nor not

            // create media source instance
            var ms = new MediaSource();

            // queue for incoming media packets
            var queue = [];

            var ws; // websocket

            // ** two callbacks ** 
            // - pushPacket : called when websocket receives data
            // - loadPacket : called when sourceBuffer is ready for more data
            // Both operate on a common fifo

            function pushPacket(arr) { // receives ArrayBuffer.  Called when websocket gets more data
                // first packet ever to arrive: write directly to sourceBuffer
                // sourceBuffer ready to accept: write directly to SourceBuffer
                // otherwise insert to fifo

                var view   = new Uint8Array(arr);
                if (verbose) { console.log("got", arr.byteLength, "bytes.  Values=", view[0], view[1], view[2], view[3], view[4]); }

                data = arr;

                if (!streamingStarted && !sourceBuffer.updating) {
                    if (verbose) console.log("Streaming started with", view[0], view[1], view[2], view[3], view[4]);
                    sourceBuffer.appendBuffer(data);
                    streamingStarted=true;
                    return;
                }

                queue.push(data); // add to the end
                if (verbose) { console.log("queue push:", queue.length); }               
            }

            function loadPacket() { // called when sourceBuffer is ready for more
               if (!sourceBuffer.updating) { // really, really ready
                    if (queue.length>0) {

                        inp = queue.shift(); // pop from the beginning
                        if (verbose) { console.log("queue PULL:", queue.length); }

                        var view = new Uint8Array(inp);

                        if (verbose) { console.log("                        writing buffer with", view[0], view[1], view[2], view[3], view[4]); }

                        sourceBuffer.appendBuffer(inp);
                        }
                    else { // the queue runs empty, so we must force-feed the next packet
                        streamingStarted = false;
                    }


                }
                else { // so it was not?
                }
            }



            function opened() { // now the MediaSource object is ready to go
                sourceBuffer = ms.addSourceBuffer(codecPars);
                sourceBuffer.addEventListener("updateend",loadPacket);

                // set up the websocket
                ws = new WebSocket("ws://videoserver");
                ws.binaryType = "arraybuffer";
                ws.onmessage = function (event) {
                    pushPacket(event.data);
                };
            }


            function startup() {
                // add event listeners
                ms.addEventListener('sourceopen',opened,false);             

                // get reference to video
                var livestream = document.getElementById('livestream');

                // set mediasource as source of video
                livestream.src = window.URL.createObjectURL(ms);
            }


            window.onload = function() {
                startup();
            }
        </script>   
</html>

Файл 'A' на 100% правильный, может воспроизводиться моим кодом.

Файл 'B' может быть не на 100% корректным, но он хорошо воспроизводится в VL C (Windows и Ubuntu), а также в «Фильмах и ТВ» на Windows, но может не воспроизводится моим кодом .

Браузеры (Chrome, Firefox) не выдают никаких сообщений об ошибках или предупреждений, когда я пытаюсь воспроизвести файл 'B'. Это просто не отображается.

Я поместил эти файлы в http://thumb.co.il, который является видеоинспектором. Файлы кажутся одинаковыми и хорошими (оба начинаются с ftyp, moov, moof, mdat).

У меня два вопроса:

  1. В чем проблема с файлом 'B'?
  2. Как я могу изменить код для воспроизведения также файла 'B'? (использование дополнительной клиентской библиотеки может быть приемлемым решением)
...