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:
Mark van Renswoude 2016-08-07 10:05:18 +02:00
parent 8d3ce97474
commit 93b5e9d7c6
5 changed files with 59 additions and 15 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
/config.js
/node_modules/
*.sublime-workspace
*.sublime-workspace
ipcam_cgi_sdk.pdf

View File

@ -51,7 +51,7 @@ app.get('/capture/:camId', function(req, res)
if (config.cams.hasOwnProperty(camId))
{
capture.start(config.cams[camId], moment());
capture.start(camId, config.cams[camId], moment());
console.log('Started capture for: ' + camId);
res.send(JSON.stringify([camId]));

View File

@ -20,6 +20,22 @@ util.inherits(FFMPEGProcessor, BaseProcessor);
FFMPEGProcessor.prototype.run = function()
{
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();
command
.input(this.cam.options.input)
@ -33,16 +49,19 @@ FFMPEGProcessor.prototype.run = function()
}
command
.output(helpers.createVariableFilename(this.cam.options.filename, this.now,
{
camId: this.camId
}))
.output(tempFilename)
.videoCodec(this.cam.options.videoCodec)
.outputFormat(this.cam.options.outputFormat);
command.on('error', function(err, stdout, stderr)
{
console.log('Error: FFmpeg output:' + err.message);
cleanup();
});
command.on('end', function()
{
self.doEnd();
cleanup();
});
self.doStart();

View File

@ -20,6 +20,14 @@ util.inherits(HTTPFFMPEGProcessor, BaseHTTPStreamProcessor);
HTTPFFMPEGProcessor.prototype.run = function()
{
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();
command
.input(this.output)
@ -29,13 +37,16 @@ HTTPFFMPEGProcessor.prototype.run = function()
command.inputOption('-use_wallclock_as_timestamps 1');
command
.output(helpers.createVariableFilename(this.cam.options.filename, this.now,
{
camId: this.camId
}))
.output(this.tempFilename)
.videoCodec(this.cam.options.videoCodec)
.outputFormat(this.cam.options.outputFormat)
.run();
.outputFormat(this.cam.options.outputFormat);
command.on('error', function(err, stdout, stderr)
{
console.log('Error: FFmpeg output:' + err.message);
});
command.run();
HTTPFFMPEGProcessor.super_.prototype.run.call(this);
}
@ -54,6 +65,11 @@ HTTPFFMPEGProcessor.prototype.cleanup = function()
this.output.end();
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;

View File

@ -15,10 +15,13 @@ util.inherits(HTTPRawProcessor, BaseHTTPStreamProcessor);
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
}));
});
this.tempFilename = this.filename + '.recording';
this.output = fs.createWriteStream(this.tempFilename);
HTTPRawProcessor.super_.prototype.run.call(this);
}
@ -41,6 +44,11 @@ HTTPRawProcessor.prototype.cleanup = function()
this.output.end();
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;