Browse Source

add --start-offset option to specify start offset override

Gil Pedersen 11 years ago
parent
commit
6a119d5271
2 changed files with 48 additions and 38 deletions
  1. 4 3
      bin/hlsrecord
  2. 44 35
      lib/recorder.js

+ 4 - 3
bin/hlsrecord

@@ -12,16 +12,17 @@ hlsrecord.version(require('../package').version)
    .option('-c, --create-dir', 'Explicitly create output dir')
    .option('-b, --begin-date <date>', 'Start recording at', dateValue)
    .option('-e, --end-date <date>', 'Stop recording at', dateValue)
+   .option('-s, --start-offset <seconds>', 'Playback start time offset', parseFloat)
 //   .option('-a, --user-agent <string>', 'HTTP User-Agent')
 //   .option('-f, --full', 'record all variants')
    .parse(process.argv);
 
 function dateValue(val) {
-  // FIXME: negative values doesn't work with commander, as
+  // FIXME: negative values doesn't work with commander - https://github.com/visionmedia/commander.js/issues/61
   if (val === 'now') return new Date();
   if (val.length && (val[0] === '+' || val[0] === '-'))
     return new Date(Math.round(new Date().getTime() / 1000 + parseInt(val, 10)) * 1000);
-  if (parseInt(val, 10) == val)
+  if (!isNaN(parseInt(val, 10)))
     return new Date(parseInt(val, 10) * 1000);
   return new Date(val);
 }
@@ -74,4 +75,4 @@ function createReader(src) {
 }
 
 var rdr = createReader(src);
-recorder(rdr, outDir, { subreader:createReader }).start();
+recorder(rdr, outDir, { subreader:createReader, startOffset: hlsrecord.startOffset }).start();

+ 44 - 35
lib/recorder.js

@@ -21,6 +21,7 @@ function HlsStreamRecorder(reader, dst, options) {
   this.seq = 0;
   this.index = null;
 
+  this.startOffset = parseFloat(options.startOffset);
   this.subreader = options.subreader;
 }
 
@@ -42,43 +43,51 @@ HlsStreamRecorder.prototype.updateIndex = function(update) {
 
   if (!this.index) {
     this.index = new m3u8parse.M3U8Playlist(update);
-    this.index.segments = [];
-    this.index.first_seq_no = self.seq;
-    this.index.type = 'EVENT';
-    this.index.ended = false;
-
-    debug('programs', this.index.programs);
-    if (this.subreader) {
-      for (var programNo in this.index.programs) {
-        var programs = this.index.programs[programNo];
-
-        // remove backup sources
-        var used = {};
-        programs = programs.filter(function(program) {
-          var bw = parseInt(program.info.bandwidth, 10);
-          var res = !(bw in used);
-          used[bw] = true;
-          return res;
-        });
-
-        this.index.programs[programNo] = programs;
-
-        programs.forEach(function(program, index) {
-          var programUrl = url.resolve(self.reader.baseUrl, program.uri);
-          debug('url', programUrl);
-          var dir = self.variantName(program.info, index);
-          program.uri = path.join(dir, 'index.m3u8');
-          program.recorder = new HlsStreamRecorder(self.subreader(programUrl), path.join(self.dst, dir)).start();
-        });
+    if (!this.index.variant) {
+      this.index.segments = [];
+      this.index.first_seq_no = self.seq;
+      this.index.type = 'EVENT';
+      this.index.ended = false;
+      this.index.discontinuity_sequence = 0; // not allowed in event playlists
+      if (!isNaN(this.startOffset)) {
+        var offset = this.startOffset;
+        if (offset < 0) offset = Math.min(offset, -3 * this.target_duration);
+        this.index.start = { offset: offset };
       }
-
-      // TODO: handle groups!!
-      this.index.groups = {};
-      this.index.iframes = {};
     } else {
-      this.index.programs = {};
-      this.index.groups = {};
-      this.index.iframes = {};
+      debug('programs', this.index.programs);
+      if (this.subreader) {
+        for (var programNo in this.index.programs) {
+          var programs = this.index.programs[programNo];
+
+          // remove backup sources
+          var used = {};
+          programs = programs.filter(function(program) {
+            var bw = parseInt(program.info.bandwidth, 10);
+            var res = !(bw in used);
+            used[bw] = true;
+            return res;
+          });
+
+          this.index.programs[programNo] = programs;
+
+          programs.forEach(function(program, index) {
+            var programUrl = url.resolve(self.reader.baseUrl, program.uri);
+            debug('url', programUrl);
+            var dir = self.variantName(program.info, index);
+            program.uri = path.join(dir, 'index.m3u8');
+            program.recorder = new HlsStreamRecorder(self.subreader(programUrl), path.join(self.dst, dir), { startOffset: self.startOffset }).start();
+          });
+        }
+
+        // TODO: handle groups!!
+        this.index.groups = {};
+        this.index.iframes = {};
+      } else {
+        this.index.programs = {};
+        this.index.groups = {};
+        this.index.iframes = {};
+      }
     }
 
     // hook end listener