Skip to content

Commit

Permalink
transcoding
Browse files Browse the repository at this point in the history
  • Loading branch information
benvanik committed Nov 16, 2011
1 parent cb95246 commit a28d62c
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 23 deletions.
13 changes: 6 additions & 7 deletions README.md
Expand Up @@ -17,13 +17,12 @@ Coming soon (maybe):

npm install transcode
node
> var transcoder = require('transcode').createTranscoder(
'input.flv',
'output.mp4', {
preset: 'appletv'
}).start(function(err, result) {
// Done!
});
> var transcode = require('transcode');
> var transcoder = transcode.createTranscoder('input.flv');
> transcoder.setProfile(transcode.profiles.APPLE_TV);
> transcoder.writeToFile('output.m4v', function(err, result) {
// Done!
});

## Installation

Expand Down
22 changes: 22 additions & 0 deletions examples/transcode.js
@@ -0,0 +1,22 @@
#!/usr/bin/env node

var transcode = require('transcode');
var util = require('util');

var paths = process.argv.slice(2);
if (!paths.length) {
util.puts('no input files');
return;
}
if (paths.length < 2) {
util.puts('no output file');
return;
}
var outputPath = paths.pop();

var transcoder = transcode.createTranscoder(paths);
transcoder.setProfile(transcode.profiles.APPLE_TV);
transcoder.writeToFile(outputPath, function(err) {
util.puts('complete!');
process.exit();
});
7 changes: 5 additions & 2 deletions lib/transcode.js
@@ -1,7 +1,10 @@
var ffmpeg = require('./transcode/ffmpeg');
var profiles = require('./transcode/profiles');

var ffmpegInfo = ffmpeg.detect();

exports.profiles = profiles;

exports.verifyConfiguration = function(callback) {
var err = null;
if (!ffmpegInfo) {
Expand All @@ -16,8 +19,8 @@ exports.verifyConfiguration = function(callback) {
};

exports.Transcoder = require('./transcode/transcoder').Transcoder;
exports.createTranscoder = function() {
return new exports.Transcoder(ffmpegInfo);
exports.createTranscoder = function(inputs) {
return new exports.Transcoder(ffmpegInfo, inputs);
};

var queryInfo = require('./transcode/mediainfo').queryInfo;
Expand Down
70 changes: 63 additions & 7 deletions lib/transcode/ffmpeg.js
Expand Up @@ -13,16 +13,41 @@ exports.detect = function() {
var Ffmpeg = function(info) {
this.info_ = info;

this.priority_ = 0;
this.inputs_ = [];
this.output_ = null;
this.options_ = {
};
};
exports.Ffmpeg = Ffmpeg;

Ffmpeg.prototype.setPriority = function(priority) {
this.priority_ = priority;
return this;
};

Ffmpeg.prototype.addInput = function(streamOrPath) {
this.inputs_.push(streamOrPath);
return this;
};

Ffmpeg.prototype.addInputs = function(inputs) {
this.inputs_ = this.inputs_.concat(inputs);
if (util.isArray(inputs)) {
this.inputs_ = this.inputs_.concat(inputs);
} else {
this.inputs_.push(inputs);
}
return this;
};

Ffmpeg.prototype.setOutput = function(streamOrPath) {
this.output_ = streamOrPath;
return this;
};

Ffmpeg.prototype.setOptions = function(options) {
this.options_ = options;
return this;
};

Ffmpeg.prototype.exec = function() {
Expand All @@ -49,17 +74,48 @@ Ffmpeg.prototype.exec = function() {
}
}

// Build args
var args = [];

// Basics
args.push('-y'); // always overwrite output files

// Input args
if (inputStream) {
args.push('-i');
args.push('-');
args.push('-i', '-');
}
for (var n = 0; n < inputPaths.length; n++) {
var inputPath = path.normalize(inputPaths[n]);
args.push('-i');
args.push(inputPath);
args.push('-i', inputPath);
}

// Real options
// TODO: options
args.push('-vcodec', 'copy');
args.push('-acodec', 'copy');

// Output
if (this.output_) {
if (typeof this.output_ == 'string') {
args.push(this.output_);
} else {
args.push('pipe:1');
}
}

// Spawn the process and wire up input (if required)
util.puts('calling ffmpeg:');
util.puts(' ' + args.join(' '));
var proc = child_process.spawn(this.info_.path, args);
if (inputStream) {
inputStream.resume();
inputStream.pipe(proc.stdin);
}

// renice to a lower priority
if (this.priority_ !== null) {
child_process.exec('renice -p ' + proc.pid + ' -n ' +
(this.priority_ ? '+' + this.priority_ : this.priority_));
}

return child_process.spawn(this.info_.path, args);
return proc;
};
3 changes: 3 additions & 0 deletions lib/transcode/profiles.js
@@ -0,0 +1,3 @@
exports.APPLE_TV = {

};
44 changes: 37 additions & 7 deletions lib/transcode/transcoder.js
Expand Up @@ -2,26 +2,56 @@ var events = require('events');
var fs = require('fs');
var util = require('util');

var Transcoder = function(ffmpegInfo) {
var queryInfo = require('./mediainfo').queryInfo;
var Ffmpeg = require('./ffmpeg').Ffmpeg;

var Transcoder = function(ffmpegInfo, inputs) {
this.ffmpegInfo_ = ffmpegInfo;

this.ffmpeg_ = new Ffmpeg(ffmpegInfo);
if (inputs) {
this.ffmpeg_.addInputs(inputs);
}

this.profile_ = null;
};
util.inherits(Transcoder, events.EventEmitter);
exports.Transcoder = Transcoder;

Transcoder.prototype.setProfile = function(profile) {
this.profile_ = profile;
};

Transcoder.prototype.attachInputStream = function(stream) {
//
this.ffmpeg_.addInput(stream);
};

Transcoder.prototype.attachInputFile = function(path) {
var stream = fs.createReadStream(path);
this.attachInputStream(stream);
this.ffmpeg_.addInput(path);
};

Transcoder.prototype.writeToStream = function(stream, callback) {
//
this.ffmpeg_.setOutput(stream);
this.write_(callback);
};

Transcoder.prototype.writeToFile = function(path, callback) {
var stream = fs.createWriteStream(path);
this.writeToStream(stream, callback);
this.ffmpeg_.setOutput(path);
this.write_(callback);
};

Transcoder.prototype.write_ = function(callback) {
// TODO: set options from profile

var proc = this.ffmpeg_.exec();

// proc.stderr.on('data', function(data) {
// util.puts('stderr: ' + data);
// });

proc.on('exit', function(code) {
if (callback) {
callback(null);
}
});
};

0 comments on commit a28d62c

Please sign in to comment.