cancel
Showing results for 
Search instead for 
Did you mean: 

PIPELINE_ERROR_DECODE in Meta Quest Browser

BFergerson
Honored Guest

I'm very new to Meta Quest development, so please let me know if this is the wrong place.

I'm trying to stream video data to my Meta Quest 3, but the Meta Quest Browser keeps throwing a PIPELINE_ERROR_DECODE error whenever I feed it data via SourceBuffer.appendBuffer(). I know this is an issue specifically with Meta Quest Browser as I've tested this code in Chrome/Firefox/Edge on Linux and Windows and they all correctly display the video. It is only when I open this HTML file in the Meta Quest Browser that there is an issue displaying the video.

The code below reproduces the error described above:

https://gist.github.com/BFergerson/808cc4c9c5eba9e0efc05033a431ced2

<!DOCTYPE html>
<html>
<head>
    <title>IE delay repro</title>
</head>
<body>
<video id="app" width="160" height="90"></video><br>
<button onclick="video.play()">Play!</button>
<div id="time"></div>
<script type="text/javascript">
    var codecs = ['video/mp4; codecs="avc1.42E01E"'];
    codecs.forEach(function(codec) {
        if (MediaSource.isTypeSupported(codec)) {
            console.log(codec + ' is supported');
        } else {
            console.log(codec + ' is not supported');
        }
    });
    var video = document.getElementById('app');
    video.addEventListener('error',function(e){
        console.error(e);
    });

    window.MediaSource = window.MediaSource || window.WebKitMediaSource;
    if (!window.MediaSource) {
        console.log('MediaSource API is not available');
    }
    var startTime = 0;
    var stopTimer = function () {
        document.getElementById('time').innerHTML = '' + ((new Date()).getTime() - startTime) + ' ms';
        video.removeEventListener('playing', stopTimer);
    };
    var mediaSource = new window.MediaSource();

    video.src=window.URL.createObjectURL(mediaSource);
    video.addEventListener('playing', stopTimer);
    var sourceBuffer;
    var buffer = []; //Frames are appended here when they 'arrive' via setInterval
    var readFromBuffer = function () {
        // Returns if the buffer is empty or has state updating
        if (buffer.length === 0 || !sourceBuffer || sourceBuffer.updating) {
            return;
        }
        try {
            var data = buffer.shift();
            sourceBuffer.appendBuffer(data);
        } catch (e) {
            console.log(e);
        }
    };
    mediaSource.addEventListener('sourceopen', function () {
        console.log('source open');
        sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E"');
        mediaSource.duration = Infinity;
        sourceBuffer.addEventListener('updateend', readFromBuffer);

    });

    //jscs:disable
    /* eslint-disable */
    var frames = ['...remove for brevity...'].map(
        function(str) {
            var raw = window.atob(str);
            var rawLength = raw.length;
            var buf = new ArrayBuffer(rawLength);
            var array = new Uint8Array(buf);

            for(i = 0; i < rawLength; i++) {
                array[i] = raw.charCodeAt(i);
            }
            return buf;
        });
    /* eslint-enable */
    video.addEventListener('play', function () {
        console.log('play clicked, starting streaming!');
        var i = 0;
        // Adds a frame to the buffer every 100 ms
        var interval = setInterval(function () {
            if(i === 0) {
                startTime = (new Date()).getTime();
            }
            if (i < frames.length) {
                buffer.push(frames[i]);
                i++;
                console.log('added frame to buffer');
                readFromBuffer();
            }
            else {
                clearInterval(interval);
            }

        }, 100);
    }, false);
</script>
</body>
</html>

 

 

0 REPLIES 0