【问题标题】:Solutions to stream from a decklink card to browsers (Gstreamer -> TCP MJPEG -> ?)从 decklink 卡流式传输到浏览器的解决方案 (Gstreamer -> TCP MJPEG -> ?)
【发布时间】:2014-06-15 02:24:21
【问题描述】:

我需要从 decklink 卡实时流式传输到浏览器。我还必须能够使用非常差的网络链接(128kbits/s...)来做到这一点,所以我需要能够以非常低的 fps(1 fps 很好)和非常低的图像质量进行流式传输。

目前我正在使用 GStreamer 从卡中获取视频,将其转码为 MJPEG,并使用 TCP 进行流式传输。这部分工作得很好,但现在我需要将此 tcp 流传输到 HTTP 流。

我可以用 VLC 做到这一点,它在“正常”帧速率(15 fps -> 0.5 秒延迟)下运行良好。但是,如果我以 1 fps 的流向 VLC 提供数据,它会引入大约 11 秒的延迟,这对我的目的来说并不好。

所以,现在我正在寻找 VLC 的替代品。我看到了 3 种方法:

  • 使用 GStreamer 的 souphttpclientsink 流式传输到 HTTP 流式服务器

  • 创建我自己的 HTTP 服务器,它监听 TCP 流并将其重新传输到客户端。我在 Python 和 Node.js 中进行了尝试,它几乎可以正常工作,但我希望有一个更强大的解决方案,就像以前的解决方案一样

  • 更棘手:创建自己的 HTTP 服务器,监听 TCP 流并使用 websockets 将数据发送到客户端,然后解码然后流客户端...

那么,我的问题是:

  • 你知道哪些 HTTP 流服务器(如果可能的话是免费的)可以与 souphttpclientsink(或 tcpclientsink)一起使用吗?

  • 您还有其他想法将 GStreamer 流传输到浏览器吗?

感谢阅读!

【问题讨论】:

    标签: http browser gstreamer live-streaming mjpeg


    【解决方案1】:

    感谢节点 Dicer 模块(感谢 this post 上的 mscdex),我让 websockets 解决方案正常工作。

    这就是我所做的:

    1°) 使用 GStreamer 通过 TCP 流式传输我的 Decklink 卡的视频:

    gst-launch -v decklinksrc mode=10 connection=0 ! deinterlace ! videorate ! videoscale ! video/x-raw-yuv, framerate=1/5, width=256, height=144 ! jpegenc quality=20 ! multipartmux  boundary="--videoboundary" ! tcpserversink host=<TCP src stream IP address> port=<TCP src stream port>
    

    2°) 用 Node 监听这个流并通过 socket.io 发送每个图像:

    // ------------------------------------------------
    // Constants :
    // ------------------------------------------------
    
    var srcHost = "<TCP src stream IP address>";
    var srcPort = <TCP src stream port>
    var srcBoundary = "--videoboundary";
    
    var destHost = "<dest IP address>";
    var destPort = <dest port>;
    
    // ------------------------------------------------
    // ------------------------------------------------
    // ------------------------------------------------
    
    
    
    // ------------------------------------------------
    // Includes :
    // ------------------------------------------------
    var Http = require('http');
    var Net = require('net');
    var Dicer = require('dicer');
    var SocketIO = require('socket.io');
    // ------------------------------------------------
    // ------------------------------------------------
    // ------------------------------------------------
    
    
    
    // ------------------------------------------------
    // TCP socket :
    // ------------------------------------------------
    
    var socket = Net.Socket();
    
    socket.connect(srcPort, srcHost, function() {
    
        // Init socket IO :
        var io = SocketIO.listen(Http.createServer().listen(destPort, destHost), { log: false });
    
        // Init Dicer :
        var dicer = new Dicer({ boundary: srcBoundary });
    
        dicer.on('part', function(part) {
    
            var frameEncoded = '';
            part.setEncoding('base64');
    
            part.on('header', function(header) { });
            part.on('data', function(data) { frameEncoded += data; });
            part.on('end', function() { io.sockets.emit('image', frameEncoded); });
        });
    
        // Handle streams closing :
        dicer.on('finish', function() { console.log('Dicer stream finished'); });
        socket.on('close', function() { console.log('TCP socket closed'); });
    
        // Pipe :
        socket.pipe(dicer);
    });
    // ------------------------------------------------
    // ------------------------------------------------
    // ------------------------------------------------
    

    3°) 在客户端监听 websocket:

    <html>
        <head>
    
            <script src="jquery-1.9.1.js"></script>
            <script src="socket.io-client/socket.io.min.js"></script>
    
            <script>
            var socket = io.connect('http://<dest IP address>:<dest port>');
            socket.on('image', function (data) {
    
                $("#video").attr("src", "data:image/jpeg;base64," + data.toString("base64") );
            });
            </script>
        </head>
    
        <body>
    
        <img id="video" style="display:block; width:400px; height:auto;" src="" />
    
        </body>
    </html>
    

    如果我得到其他解决方案,我会更新这篇文章(但我可能会选择这个)。

    【讨论】:

      猜你喜欢
      • 2011-07-13
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 2013-04-18
      • 1970-01-01
      • 2014-11-10
      • 2017-02-10
      • 1970-01-01
      相关资源
      最近更新 更多