2014-04-29 21 views
4

我需要從甲板連接卡實時流到瀏覽器。我也必須能夠通過非常差的網絡鏈接(128kbits/s ...)來實現它,所以我需要能夠以非常低的fps(1 fps很好)和非常低的圖像質量進行流式傳輸。從甲板連接卡流到瀏覽器的解決方案(Gstreamer - > TCP MJPEG - >?)

目前我正在使用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流到瀏覽器?

感謝您的閱讀!

回答

4

我得到了websockets解決方案,感謝節點Dicer模塊(並且感謝mscdex在this post上)。

因此,這裏是我做過什麼:

1°)碼流我的DeckLink卡在TCP視頻蒙山的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°)聽此流與節點,並通過套接字發送的每個圖像.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°)聽客戶端上的網頁套接字:

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

我會更新這個帖子,如果我得到其他解決方案的工作(但我可以去這個)。