FFMPEG зависает весь процесс nodejs - PullRequest
4 голосов
/ 26 июня 2011

Я пытаюсь сделать эскиз видео с помощью ffmpeg. Видеоданные принимаются в виде HTTP-запроса, а затем передаются в ffmpeg. Проблема в том, что после завершения дочернего процесса 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) {
        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');

ничего не делает, клиент никогда не получает ответ.

Ответы [ 2 ]

5 голосов
/ 28 июня 2011

После двух дней отладки и поиска в Google Кажется, я нашел проблему. В node.js есть две связанные открытые ошибки:

Я попытаюсь описать, в чем, на мой взгляд, проблема с методом pipe:

Поток запроса не может вызвать end в ffmpeg.stdin (возможно, ошибка # 777), это вызывает ошибку сломанного канала, но node.js не обрабатывает ошибку из-за ошибки # 782, в то время как поток запроса остается приостановленным - блокирует любой ответ от отправки.

Хак / обходной путь - возобновить поток запросов после выхода из 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 голосов
/ 27 июня 2011

Я бы попробовал что-то вроде этого.

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");

Вы пытаетесь передать данные в сокет перед отправкой заголовка.

...