2013-10-31 294 views
3

我在寫一個代理mjpeg視頻流的應用程序。我認爲從mjpeg服務器(我從代理服務器上提供的那個服務器)中提取mjpeg中的每個幀將會很酷,使用base64對其進行編碼並將該幀發佈到websockets上,以便將其作爲data-uri映像進行渲染前端。這樣,不支持mjpeg的客戶端就可以將實時視頻視爲一系列圖像。從MJPEG流中提取JPEG並通過websocket發佈base64編碼圖像

問題是,我不知道如何從MJPEG邊界之間提取jpeg數據。下面介紹一下邊界(標題一起)看起來像:

--------JPEG_FRAME_BOUNDARY 
Content-Type: image/jpeg 
Content-Length: 33377 
X-Frame-Epoc-HiRes: 1383166748.031929 
X-Frame-Timestamp: 2013-10-30T20:59:08.031929Z 
X-Resource-Status: active 

在這些邊界和頭兩側是亂碼數據的一堆,我認爲是原始JPEG圖像。

我正在用一個http請求獲取mjpeg,這個http請求用一系列的組塊響應,直到流結束(大約一分鐘後)。

var boundary = extractBoundary(response.headers['content-type']) 
    , buffer = []; 

response.on('data', function(chunk) { 
    buffer.push(chunk); 

    var frames = getFrames(buffer, boundary); 

    if(frames[0]) { 
     camera.set('data', "data:image/jpeg;base64," + frames[0]); 
    } 
    if(frames[1]) { 
     buffer = [new Buffer(frames[1])]; 
    } 
}); 

response.on('end', function() { 
    console.log('done'); 
}); 

現在我只需要弄清楚什麼是「getFrames」必須做檢查,如果緩衝區包含一個完整的圖像,然後返回圖像與緩衝區的剩餘塊沿base64編碼字符串(包含下一個圖像標題的位,開)。

+0

見http://stackoverflow.com/questions/4378909/how-to-save-a -mjpeg流至磁盤-C-NET/24329113#24329113 – Jay

回答

0

所以不知何故,我錯過了Paparazzo.js - 這真棒,節省了我大量的時間。基本上,解析出標題時需要知道兩件重要的事情。首先,你需要知道最後的標題行將會是什麼(我的是「X-Resource-Status:active」)。讓我震驚的是,你需要使用\ s而不是\ r \ n作爲頭部的結尾。所以,你應該配合是這樣的:

var headerEnd = remaining.match(/X-Resource-Status: active\s+/); 

您可以通過塊基本循環從流接收並找到最後頭的末尾的索引。您從最後一個標頭的端點開始獲取子字符串,然後等待直到再次調用處理程序以查找下一個標頭的開頭。

下一個棘手的問題是您必須使用緩衝區將圖像轉換爲base64(或任何其他格式)。因此,您不必採用剛解析出的框架並調用.toString('base64'),您必須執行新的Buffer(image).toString('base64')。

這裏的鏈接到狗仔隊源這樣你就可以得到什麼我談論的一個更好的主意:https://github.com/wilhelmbot/Paparazzo.js/blob/master/src/paparazzo.js