如何在 Safari 中追加通过 websocket 从 MediaSource 接收的 event.data 缓冲区

问题描述 投票:0回答:1

我目前正在创建一个简单的页面,它获取通过 Web 套接字接收的数据并将其作为 HTML 分发到网页。在除 Safari 浏览器之外的其他浏览器中,appendBuffer 可以很好地将通过 websocket 接收到的 event.data 从 MediaSource 分发到页面,但我读到 Safari 不支持 MediaSource。那么,有没有一种方法可以不使用hls,按原样接收websocket数据并显示在屏幕上呢?我的来源如下。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Video Stream Example</title>
</head>
<body>
    <div class="col">
        <video class="video-background" id="livestream" style="width:1500px; transform:rotate(180deg);" autoplay loop muted playsinline></video>
    </div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
    $(document).ready(() => {
        startPlay();
    });

    let mseQueue = [],
        mseSourceBuffer, mseStreamingStarted = false, videoSound = false;

    var ws;
    const wsUrl = `{websocket url}`;

    function startPlay() {
        const browser = getBrowser();
        if (browser === 'Safari') {
            // Sources to be added in Safari
        } else {
            openws(true);
        }
        
    }

    function openws(start) {
        const mse = new MediaSource();
        const livestream = document.getElementById('livestream');
        livestream.src = URL.createObjectURL(mse);

        mse.addEventListener('sourceopen', function() {
            ws = new WebSocket(wsUrl);
            ws.binaryType = "arraybuffer";

            ws.onopen = function() {
                console.log('Connected to WebSocket');
            };

            ws.onmessage = function(event) {
                const data = new Uint8Array(event.data);
                if (data[0] === 9) {
                    const decodedArr = data.slice(1);
                    const mimeCodec = new TextDecoder("utf-8").decode(decodedArr);

                    if (mimeCodec.indexOf(',') > 0) {
                        videoSound = true;
                    }
                    console.log('second packet with codec data: ' + mimeCodec);
                    mseSourceBuffer = mse.addSourceBuffer(`video/mp4; codecs="${mimeCodec}"`);
                    mseSourceBuffer.mode = "segments";
                    mseSourceBuffer.addEventListener("updateend", pushPacket);
                } else {
                    readPacket(event.data);
                }
            };

            ws.onerror = function (event) {
                console.log('WebSocket error '+event.data);
                setTimeout(function() {
                    openws(false);
                }, 1000);
            };

            ws.onclose = function (event) {
                console.log('WebSocket reconnection opened');
                console.log(event.code);

                if (!event.wasClean) {
                    console.log('WebSocket not was clean close..');
                }
                setTimeout(function() {
                    openws(false);
                }, 10000);
            };
        });
    }

    function pushPacket() {
        if (!mseSourceBuffer.updating) {
            if (mseQueue.length > 0) {
                const packet = mseQueue.shift();
                mseSourceBuffer.appendBuffer(packet);
                mseSourceBuffer.remove(packet);
            } else {
                mseStreamingStarted = false;
            }
        }
        
       
        const livestream = document.getElementById('livestream');

        if (livestream.buffered.length > 0) {
            if (document.hidden && !videoSound) {
                livestream.currentTime = livestream.buffered.end(livestream.buffered.length - 1) - 0.5;
            }
        }
    }

    function readPacket(packet) {
        if (!mseStreamingStarted) {
            mseSourceBuffer.appendBuffer(packet);
            mseStreamingStarted = true;
            return;
        }

        mseQueue.push(packet);

        if (!mseSourceBuffer.updating) {
            pushPacket();
        }
    }

    document.getElementById('livestream').addEventListener('loadeddata', () => {
        const livestream = document.getElementById('livestream');
        livestream.play();
    });

    document.getElementById('livestream').addEventListener('pause', () => {
        const livestream = document.getElementById('livestream');
        if (livestream.currentTime > livestream.buffered.end(livestream.buffered.length - 1)) {
            livestream.currentTime = livestream.buffered.end(livestream.buffered.length - 1) - 0.1;
            livestream.play();
        }
    });

    function getBrowser() {
        const ua = navigator.userAgent;

        if (/^((?!chrome|android).)*safari/i.test(ua)) {
            return 'Safari';
        }

        if (/chrome|crios/i.test(ua) && !/edge|edg|opr|opera|brave/i.test(ua)) {
            return 'Chrome';
        }

        return 'Other';
    }
</script>
</body>
</html>

如果您在源代码中发现任何奇怪的内容,请告诉我。我们计划创建一个网页,不仅可以在 Safari 上运行,还可以在 iOS、Mac 和 Windows 上运行。

iphone ipad safari html5-video mobile-safari
1个回答
0
投票

块引用 没有 HLS”?您可以使用像 PHP 这样的服务器端语言吗?您需要一个 PHP 脚本来获取或接收套接字数据并将其发送出去(发送到任何称为脚本的地方,例如视频标签) //sd/下载/

© www.soinside.com 2019 - 2024. All rights reserved.