Skip to content
This repository was archived by the owner on Mar 25, 2019. It is now read-only.

Commit 290b220

Browse files
committed
resolve conflicts
2 parents da2d8cd + eb6114f commit 290b220

4 files changed

Lines changed: 53 additions & 36 deletions

File tree

CHANGELOG.markdown

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## codem-transcode 0.5.10 (2015/09/16) ##
2+
3+
* Increase maxBuffer to 4MB to compensate for older ffmpegs
4+
5+
## codem-transcode 0.5.9 (2015/09/03) ##
6+
7+
* Fix for lingering "processing" jobs. (#42)
8+
* Encoder options can be an array instead of a string as well (to allow complex filters)
9+
110
## codem-transcode 0.5.8 (2015/07/05) ##
211

312
* Prevent transcoder from returning a negative freeSlot count (@larsfi).

README.markdown

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,10 @@ The `thumbnail_options` object is optional and contains a set of thumbnails that
166166

167167
If you specify thumbnails but an error occurs during generation, your job will be marked as failed. If you don't specify a valid `seconds` or `percentages` option thumbnail generation will be skipped but the job can still be completed successfully.
168168

169+
### Segmenting / HLS
170+
169171
The `segments_options` object is optional and contains segment time (duration) in seconds. Segmented videos are used in [HLS](https://en.wikipedia.org/wiki/HTTP_Live_Streaming). These options are applied to the encoded video, thus `encoder_options` are required. Moreover `encoder_options` should prepare video for segmenting, because bitstream
170-
filter [h264_mp4toannexb](https://www.ffmpeg.org/ffmpeg-bitstream-filters.html#h264_005fmp4toannexb) will be applied to the video. Therefore it is recommended to transcode to an MP4 file before segmenting.
172+
filter [h264_mp4toannexb](https://www.ffmpeg.org/ffmpeg-bitstream-filters.html#h264_005fmp4toannexb) will be applied to the video. Therefore it is recommended to transcode to an MP4 file before segmenting. Segmenting works by taking the output file from your transcoder job and applying segmenting to it.
171173

172174
The segmenting command looks like:
173175

lib/job.js

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ var StatusCodes = {
1919

2020
var JobUtils = {
2121
sql: null,
22-
22+
2323
generateThumbnailPath: function(destinationFile, offset, format) {
24-
return [path.dirname(destinationFile), path.basename(destinationFile, path.extname(destinationFile))].join(path.sep) + "-" + offset + "." + format;
24+
return [path.dirname(destinationFile), path.basename(destinationFile, path.extname(destinationFile))].join(path.sep) + "-" + offset + "." + format;
2525
},
26-
26+
2727
generateRangeFromThumbOpts: function(thumbOpts, duration) {
2828
if (thumbOpts['percentages']) {
2929
// percentage based thumbnails
@@ -35,7 +35,7 @@ var JobUtils = {
3535
return null;
3636
}
3737
},
38-
38+
3939
getDatabase: function() {
4040
if (JobUtils.sql == null) {
4141
if (config['database']['dialect'] == "sqlite") {
@@ -50,8 +50,9 @@ var JobUtils = {
5050
storage: config['database']['database'],
5151
host: config['database']['host'],
5252
port: config['database']['port'],
53-
logging: false,
5453
omitNull: true
54+
pool: false,
55+
logging: false
5556
});
5657
}
5758
}
@@ -74,7 +75,7 @@ var JobUtils = {
7475
});
7576
callback(null);
7677
},
77-
78+
7879
migrateDatabase: function(callback) {
7980
var migrator = JobUtils.getDatabase().getMigrator({path: __dirname + "/../migrations" });
8081
migrator.migrate().success(function() {
@@ -83,14 +84,14 @@ var JobUtils = {
8384
callback(err);
8485
});
8586
},
86-
87+
8788
pad: function(orig, padString, length) {
8889
var str = orig;
8990
while (str.length < length)
9091
str = padString + str;
9192
return str;
9293
},
93-
94+
9495
percentagesToRange: function(percentages, duration) {
9596
if (Array.isArray(percentages)) {
9697
// explicit percentages
@@ -104,7 +105,7 @@ var JobUtils = {
104105
return offsets;
105106
}
106107
},
107-
108+
108109
secondsToRange: function(seconds, duration) {
109110
if (Array.isArray(seconds)) {
110111
// explicit percentages
@@ -118,7 +119,7 @@ var JobUtils = {
118119
return offsets;
119120
}
120121
},
121-
122+
122123
verifyDatabase: function(callback) {
123124
JobUtils.getDatabase().getQueryInterface().showAllTables().success(function (tables) {
124125
if (tables.length > 0 && tables.indexOf('SequelizeMeta') == -1) {
@@ -220,12 +221,12 @@ var Job = JobUtils.getDatabase().define('Job', {
220221
if (err) {
221222
fs.stat(destination_dir, function(err, stats) {
222223
if (err) {
223-
job.exitHandler(-1, "unable to create output directory (" + destination_dir + ").");
224+
job.exitHandler(-1, "unable to create output directory (" + destination_dir + ").");
224225
} else {
225226
if (stats.isDirectory()) {
226-
callback("hasOutputDir");
227+
callback("hasOutputDir");
227228
} else {
228-
job.exitHandler(-1, "unable to create output directory (" + destination_dir + ").");
229+
job.exitHandler(-1, "unable to create output directory (" + destination_dir + ").");
229230
}
230231
}
231232
});
@@ -265,8 +266,8 @@ var Job = JobUtils.getDatabase().define('Job', {
265266
var null_file = (!!os.platform().match(/^win/) ? 'nul' : '/dev/null');
266267
args.push('-f', 'null', '-acodec', 'copy', '-vcodec', 'copy', '-y', null_file);
267268
}
268-
269-
var the_process = child_process.spawn(config['encoder'], args);
269+
270+
var the_process = child_process.spawn(config['encoder'], args);
270271

271272
the_process.stderr.on('data', function(data) { job.progressHandler(data); });
272273
the_process.on('error', function(err) { job.lastMessage = 'Unable to execute the ffmpeg binary: ' + err; job.didFinish(1); });
@@ -316,14 +317,14 @@ var Job = JobUtils.getDatabase().define('Job', {
316317
var playlistPath = [playlistDir, playlistName].join(path.sep) + '.m3u8';
317318
var segmentsFormat = [playlistDir, playlistName].join(path.sep) + '-%06d.ts'
318319
var inputFile = (this.parsedOpts()['encoder_options'].length > 0) ? job.tmpFile : this.parsedOpts()['source_file']
319-
320+
320321
args.push('-i', inputFile,
321322
'-codec', 'copy', '-map', '0', '-f', 'segment',
322323
'-vbsf', 'h264_mp4toannexb', '-flags', '-global_header',
323324
'-segment_format', 'mpegts', '-segment_list', playlistPath,
324325
'-segment_time', segmentTime, segmentsFormat);
325326

326-
child_process.execFile(config['encoder'], args, function(error, stdout, stderr) {
327+
child_process.execFile(config['encoder'], args, { maxBuffer: 4096*1024 }, function(error, stdout, stderr) {
327328
if (error) {
328329
job.lastMessage = 'Error while generating segments: ' + error.message;
329330
callbacks.error(job);
@@ -386,20 +387,20 @@ var Job = JobUtils.getDatabase().define('Job', {
386387
return function(callback) {
387388
var thumbOpts = job.parsedOpts()['thumbnail_options'];
388389
var args = ['-ss', offset, '-i', job.parsedOpts()['source_file'], '-vframes', '1', '-y'];
389-
390+
390391
// Explicit size provided
391392
if (thumbOpts['size'] && thumbOpts['size'] != 'src') {
392393
args.push('-s', thumbOpts['size']);
393394
}
394395

395396
var format = thumbOpts['format'] ? thumbOpts['format'] : 'jpg';
396397
var destinationFile = job.parsedOpts()['destination_file'];
397-
398+
398399
// Destination file + offset + extension
399400
var outputFile = JobUtils.generateThumbnailPath(destinationFile, offset, format);
400401
args.push(outputFile);
401-
402-
var thumb_process = child_process.execFile(config['encoder'], args, function(error, stdout, stderr) {
402+
403+
var thumb_process = child_process.execFile(config['encoder'], args, { maxBuffer: 4096*1024 }, function(error, stdout, stderr) {
403404
if (error) {
404405
callback(new Error('Error while generating thumbnail: ' + error.message), null);
405406
} else {
@@ -473,6 +474,8 @@ var Job = JobUtils.getDatabase().define('Job', {
473474
return obj;
474475
},
475476
progressHandler: function(data) {
477+
if (this.hasExited) return;
478+
476479
this.lastMessage = data.toString().replace("\n",'');
477480

478481
(isNaN(this.duration) || this.duration == 0) ? this.extractDuration(data.toString()) : this.extractProgress(data.toString());
@@ -495,11 +498,11 @@ var Job = JobUtils.getDatabase().define('Job', {
495498

496499
this.duration = hours * 3600 + minutes * 60 + seconds;
497500
notifyHandler.notify(this);
498-
}
501+
}
499502
},
500503
extractProgress: function(text) {
501504
// 00:00:00 (hours, minutes, seconds)
502-
var re = new RegExp(/time=(\d{2}):(\d{2}):(\d{2})/);
505+
var re = new RegExp(/time=(\d{2}):(\d{2}):(\d{2})/);
503506
var m = re.exec(text);
504507

505508
if (m != null) {
@@ -508,7 +511,7 @@ var Job = JobUtils.getDatabase().define('Job', {
508511
this.progress = current / this.duration;
509512
} else {
510513
// 00.00 (seconds, hundreds)
511-
re = new RegExp(/time=(\d+).(\d{2})/);
514+
re = new RegExp(/time=(\d+).(\d{2})/);
512515
m = re.exec(text);
513516

514517
if (m != null) {
@@ -518,18 +521,21 @@ var Job = JobUtils.getDatabase().define('Job', {
518521
}
519522
},
520523
exitHandler: function(code, message) {
521-
if (!this.hasExited) {
522-
this.hasExited = true
523-
this.status = (code == 0 ? 'success' : 'failed');
524-
this.message = message;
525-
526-
if (this.status == 'success' && !isNaN(this.progress)) {
527-
this.progress = 1.0;
528-
}
524+
this.hasExited = true
525+
this.message = message;
529526

530-
this.save();
531-
this.completeCallback();
527+
if (code == 0) {
528+
this.progress = 1.0;
532529
}
530+
531+
this.status = (code == 0 ? StatusCodes.SUCCESS : StatusCodes.FAILED);
532+
this.save().success(function() {
533+
// successfull save
534+
}).error(function(err) {
535+
// error while saving job
536+
logger.log("Error while saving job: " + err)
537+
});
538+
this.completeCallback();
533539
}
534540
}
535541
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "codem-transcode",
33
"description": "Offline video transcoding using ffmpeg, with a small HTTP API.",
4-
"version": "0.5.8",
4+
"version": "0.5.10",
55
"keywords": ["transcoding", "ffmpeg", "video"],
66
"homepage": "http://www.transcodem.com/",
77
"repository": {

0 commit comments

Comments
 (0)