Solutions to stream from a decklink card to browsers (Gstreamer -> TCP MJPEG -> ?)

 ̄綄美尐妖づ 提交于 2019-12-20 14:40:07

问题


I need to live stream from a decklink card to a browser. I also must be able to do it with a very poor network link (128kbits/s...), so I need to be able to stream at a very low fps (1 fps is fine) and a very low image quality.

At the moment I'm using GStreamer to get the video from the card, to transcode it to MJPEG, and to stream it with TCP. This part is perfectly working, but now I need to tube this tcp stream to an HTTP stream.

I can do this with VLC and it works well at a "normal" framerate (15 fps -> 0.5 sec of latency). But if I feed VLC with a 1 fps stream, it introduces a latency of around 11 sec, which is not fine for my purpose.

So, now I'm looking for a replacement of VLC. I see 3 ways of doing it :

  • use the GStreamer's souphttpclientsink to stream to an HTTP streaming server

  • create my own HTTP server, wich listens to the TCP stream and re-streams it to the clients. I tried in Python and Node.js and it is nearly working, but I would prefer to have a more robust solution like the previous one

  • even more tricky : create my own HTTP server, listen to the TCP stream and send the data to the client with websockets, and then decode then stream client side...

Then, my questions are :

  • do you know which HTTP streaming servers (if possible free) are usable with souphttpclientsink (or tcpclientsink) ?

  • do you have any other idea to stream a GStreamer stream to a browser ?

Thanks for reading !


回答1:


I got the websockets solution working, thanks to the node Dicer module (and thanks to mscdex on this post ).

So here is what I did :

1°) Stream my Decklink card's video over TCP whith GStreamer :

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°) Listen to this stream with Node and send each image via 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°) Listen to the websocket on the client :

<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>

I will update this post if I get other solutions working (but I may go with this one).



来源:https://stackoverflow.com/questions/23359736/solutions-to-stream-from-a-decklink-card-to-browsers-gstreamer-tcp-mjpeg

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!