Added error handling to FFmpeg (to prevent process shutdown)
Files are now written to a '.recording' file first and moved afterwards
This commit is contained in:
parent
8d3ce97474
commit
93b5e9d7c6
|
@ -1,3 +1,4 @@
|
||||||
/config.js
|
/config.js
|
||||||
/node_modules/
|
/node_modules/
|
||||||
*.sublime-workspace
|
*.sublime-workspace
|
||||||
|
ipcam_cgi_sdk.pdf
|
2
index.js
2
index.js
|
@ -51,7 +51,7 @@ app.get('/capture/:camId', function(req, res)
|
||||||
|
|
||||||
if (config.cams.hasOwnProperty(camId))
|
if (config.cams.hasOwnProperty(camId))
|
||||||
{
|
{
|
||||||
capture.start(config.cams[camId], moment());
|
capture.start(camId, config.cams[camId], moment());
|
||||||
|
|
||||||
console.log('Started capture for: ' + camId);
|
console.log('Started capture for: ' + camId);
|
||||||
res.send(JSON.stringify([camId]));
|
res.send(JSON.stringify([camId]));
|
||||||
|
|
|
@ -20,6 +20,22 @@ util.inherits(FFMPEGProcessor, BaseProcessor);
|
||||||
FFMPEGProcessor.prototype.run = function()
|
FFMPEGProcessor.prototype.run = function()
|
||||||
{
|
{
|
||||||
var self = this;
|
var self = this;
|
||||||
|
var filename = helpers.createVariableFilename(this.cam.options.filename, this.now,
|
||||||
|
{
|
||||||
|
camId: this.camId
|
||||||
|
});
|
||||||
|
|
||||||
|
var tempFilename = filename + '.recording';
|
||||||
|
var cleanup = function()
|
||||||
|
{
|
||||||
|
fs.rename(tempFilename, filename, function(err)
|
||||||
|
{
|
||||||
|
console.log('Error: could not move ' + tempFilename + ' to ' + filename + ': ' + err.message);
|
||||||
|
self.doEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var command = new FfmpegCommand();
|
var command = new FfmpegCommand();
|
||||||
command
|
command
|
||||||
.input(this.cam.options.input)
|
.input(this.cam.options.input)
|
||||||
|
@ -33,16 +49,19 @@ FFMPEGProcessor.prototype.run = function()
|
||||||
}
|
}
|
||||||
|
|
||||||
command
|
command
|
||||||
.output(helpers.createVariableFilename(this.cam.options.filename, this.now,
|
.output(tempFilename)
|
||||||
{
|
|
||||||
camId: this.camId
|
|
||||||
}))
|
|
||||||
.videoCodec(this.cam.options.videoCodec)
|
.videoCodec(this.cam.options.videoCodec)
|
||||||
.outputFormat(this.cam.options.outputFormat);
|
.outputFormat(this.cam.options.outputFormat);
|
||||||
|
|
||||||
|
command.on('error', function(err, stdout, stderr)
|
||||||
|
{
|
||||||
|
console.log('Error: FFmpeg output:' + err.message);
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
command.on('end', function()
|
command.on('end', function()
|
||||||
{
|
{
|
||||||
self.doEnd();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
self.doStart();
|
self.doStart();
|
||||||
|
|
|
@ -20,6 +20,14 @@ util.inherits(HTTPFFMPEGProcessor, BaseHTTPStreamProcessor);
|
||||||
HTTPFFMPEGProcessor.prototype.run = function()
|
HTTPFFMPEGProcessor.prototype.run = function()
|
||||||
{
|
{
|
||||||
this.output = new stream.PassThrough();
|
this.output = new stream.PassThrough();
|
||||||
|
this.filename = helpers.createVariableFilename(this.cam.options.filename, this.now,
|
||||||
|
{
|
||||||
|
camId: this.camId
|
||||||
|
});
|
||||||
|
|
||||||
|
this.tempFilename = filename + '.recording';
|
||||||
|
|
||||||
|
|
||||||
var command = new FfmpegCommand();
|
var command = new FfmpegCommand();
|
||||||
command
|
command
|
||||||
.input(this.output)
|
.input(this.output)
|
||||||
|
@ -29,13 +37,16 @@ HTTPFFMPEGProcessor.prototype.run = function()
|
||||||
command.inputOption('-use_wallclock_as_timestamps 1');
|
command.inputOption('-use_wallclock_as_timestamps 1');
|
||||||
|
|
||||||
command
|
command
|
||||||
.output(helpers.createVariableFilename(this.cam.options.filename, this.now,
|
.output(this.tempFilename)
|
||||||
{
|
|
||||||
camId: this.camId
|
|
||||||
}))
|
|
||||||
.videoCodec(this.cam.options.videoCodec)
|
.videoCodec(this.cam.options.videoCodec)
|
||||||
.outputFormat(this.cam.options.outputFormat)
|
.outputFormat(this.cam.options.outputFormat);
|
||||||
.run();
|
|
||||||
|
command.on('error', function(err, stdout, stderr)
|
||||||
|
{
|
||||||
|
console.log('Error: FFmpeg output:' + err.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
command.run();
|
||||||
|
|
||||||
HTTPFFMPEGProcessor.super_.prototype.run.call(this);
|
HTTPFFMPEGProcessor.super_.prototype.run.call(this);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +65,11 @@ HTTPFFMPEGProcessor.prototype.cleanup = function()
|
||||||
this.output.end();
|
this.output.end();
|
||||||
this.output = null;
|
this.output = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs.rename(this.tempFilename, this.filename, function(err)
|
||||||
|
{
|
||||||
|
console.log('Error: could not move ' + this.tempFilename + ' to ' + this.filename + ': ' + err.message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = HTTPFFMPEGProcessor;
|
module.exports = HTTPFFMPEGProcessor;
|
|
@ -15,10 +15,13 @@ util.inherits(HTTPRawProcessor, BaseHTTPStreamProcessor);
|
||||||
|
|
||||||
HTTPRawProcessor.prototype.run = function()
|
HTTPRawProcessor.prototype.run = function()
|
||||||
{
|
{
|
||||||
this.output = fs.createWriteStream(helpers.createVariableFilename(this.cam.options.filename, this.now,
|
this.filename = helpers.createVariableFilename(this.cam.options.filename, this.now,
|
||||||
{
|
{
|
||||||
camId: this.camId
|
camId: this.camId
|
||||||
}));
|
});
|
||||||
|
|
||||||
|
this.tempFilename = this.filename + '.recording';
|
||||||
|
this.output = fs.createWriteStream(this.tempFilename);
|
||||||
|
|
||||||
HTTPRawProcessor.super_.prototype.run.call(this);
|
HTTPRawProcessor.super_.prototype.run.call(this);
|
||||||
}
|
}
|
||||||
|
@ -41,6 +44,11 @@ HTTPRawProcessor.prototype.cleanup = function()
|
||||||
this.output.end();
|
this.output.end();
|
||||||
this.output = null;
|
this.output = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs.rename(this.tempFilename, this.filename, function(err)
|
||||||
|
{
|
||||||
|
console.log('Error: could not move ' + this.tempFilename + ' to ' + this.filename + ': ' + err.message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = HTTPRawProcessor;
|
module.exports = HTTPRawProcessor;
|
Loading…
Reference in New Issue