FFMPEG挂掉了整个nodejs进程

发布于 2024-11-17 08:31:14 字数 758 浏览 3 评论 0原文

我想做的是使用 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');

不执行任何操作,客户端永远不会收到响应。

What I am trying to do is to make a thumbnail of a video using ffmpeg. The video data is received in a HTTP request and then piped to ffmpeg. The problem is that once the ffmpeg child process exits I simply can't send the response back.

Here is the code:

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

The problem is that calling:

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

does nothing, the client never receives the response.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

勿忘初心 2024-11-24 08:31:14

经过两天的调试和谷歌搜索,我似乎找到了问题所在。
Node.js 中有两个相关的未解决错误:

我将尝试描述我认为“管道”方法的问题所在:

请求流无法调用 ffmpeg.stdin 上的结束(可能是错误#777),这会导致管道损坏错误,但 Node.js 不会处理由于 bug #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 版本出现问题

After two days of debugging and googling It seems like I have found the problem.
There are two related open bugs in node.js responsible:

I will try to describe what I think the problem is with the 'pipe' method:

The request stream fails to invoke end on ffmpeg.stdin (probably bug #777), this causes a broken pipe error, but node.js doesn't handle the error because of bug #782, meanwhile the request stream remains paused - this blocks any response from being sent.

The hack/workaround is to resume the request stream once ffmpeg exits.

Here is the fixed code sample:

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

Please keep in mind that this is a hack/workaround and may lead to problems with future node.js releases once they do something about those bugs

半仙 2024-11-24 08:31:14

我会尝试这样的事情。

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

您正在尝试在发送标头之前将数据通过管道传输到套接字。

I would try something like this.

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

You are trying to pipe out data to the socket before sending the header.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文