我需要从decklink卡直播到浏览器。我也必须能够使用非常差的网络链接(128kbits / s ...),因此我需要能够以非常低的fps(1 fps很好)和非常低的图像质量进行流式传输。 / p>
目前我正在使用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流流式传输到浏览器吗?
感谢阅读!
答案 0 :(得分:6)
我得到了websockets解决方案,感谢节点Dicer模块(感谢this post上的mscdex)。
所以这就是我所做的:
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>
如果我得到其他解决方案,我会更新这篇文章(但我可以选择这个)。