2011-06-26 97 views
4

我想要做的是使用ffmpeg製作視頻的縮略圖。視頻數據通過HTTP請求接收,然後通過管道傳輸到ffmpeg。問題是,一旦ffmpeg子進程退出,我根本無法發回響應。FFMPEG掛起整個nodejs進程

下面是代碼:

var http = require('http'), 
sys = require('sys'), 
child = require('child_process') 
http.createServer(function (req, res) { 
    im = child.spawn('ffmpeg',['-i','-','-vcodec','mjpeg','-ss','00:00:03','-vframes','1','-s','100x80','./thumb/thumbnail.jpg']); 
    im.on('exit', function (code, signal) { 
     res.writeHead(200, {'Content-Type': 'text/plain'}); 
     res.end('{"success":true}\n'); 
    }); 
    req.connection.pipe(im.stdin); 
}).listen(5678, "127.0.0.1"); 

的問題是,美其名曰:

res.writeHead(200, {'Content-Type': 'text/plain'}); 
res.end('{"success":true}\n'); 

什麼都不做,客戶端永遠不會收到響應。

+0

我不熟悉node.js,但我無法想象你需要創建寫入原始json作爲字符串發送json回到用戶... – ThiefMaster

回答

5

經過兩天的調試和谷歌搜索似乎我發現了這個問題。 有兩個與開放的錯誤在node.js中負責:

我會盡力來形容我認爲這個問題是與「管」的方法:

請求流無法在ffmpeg.stdin(可能是錯誤#777)上調用結束,這會導致管道錯誤錯誤,但由於錯誤#782,node.js不處理錯誤,同時請求流保持暫停 - 這個阻止發送的任何響應。

黑客/解決方法是在ffmpeg退出後恢復請求流。

這裏是固定的代碼示例:

var http = require('http'), 
sys = require('sys'), 
child = require('child_process') 
http.createServer(function (req, res) { 
im = child.spawn('ffmpeg',['-i','-','-vcodec','mjpeg','-ss','00:00:03','-vframes','1','-s','100x80','./thumb/thumbnail.jpg']); 
    im.on('exit', function (code, signal) { 
     req.resume(); 
     res.writeHead(200, {'Content-Type': 'text/plain'}); 
     res.end('{"success":true}\n'); 
    }); 
    req.connection.pipe(im.stdin); 
}).listen(5678, "127.0.0.1"); 

請記住,這是一個黑客/解決方法,並可能導致node.js的釋放與未來的問題,一旦他們做些什麼這些錯誤

2

我會嘗試這樣的事情。

var http = require('http'): 
var sys = require('sys'): 
var child = require('child_process'): 

http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    im = child.spawn('ffmpeg',['-i','-','-vcodec','mjpeg','-ss','00:00:03','-vframes','1','-s','100x80','./thumb/thumbnail.jpg']); 
    im.on('exit', function (code, signal) { 
     res.end('{"success":true}\n'); 
    }); 
    req.connection.pipe(im.stdin); 
}).listen(5678, "127.0.0.1"); 

您正試圖在發送標頭之前將數據發送到套接字。

+0

我已經嘗試過這樣做,它沒有奏效。正如我在問題中所說的那樣,創建了縮略圖並按照它應該調用了子進程「退出」事件,但問題是永遠不會發送響應。似乎ffmpeg以某種方式干擾了服務器響應。 – rcode