|
|
@@ -10,7 +10,7 @@ var fs = require('fs'),
|
|
|
var mime = require('mime-types'),
|
|
|
StreamEach = require('stream-each'),
|
|
|
oncemore = require('oncemore'),
|
|
|
- m3u8parse = require('m3u8parse'),
|
|
|
+ M3U8Parse = require('m3u8parse'),
|
|
|
mkdirp = require('mkdirp'),
|
|
|
writeFileAtomic = require('write-file-atomic'),
|
|
|
debug = require('debug')('hls:recorder');
|
|
|
@@ -57,8 +57,8 @@ HlsStreamRecorder.prototype.updateIndex = function(update) {
|
|
|
if (!update) return;
|
|
|
|
|
|
if (!this.index) {
|
|
|
- this.index = new m3u8parse.M3U8Playlist(update);
|
|
|
- if (!this.index.variant) {
|
|
|
+ this.index = new M3U8Parse.M3U8Playlist(update);
|
|
|
+ if (!this.index.master) {
|
|
|
if (this.collect)
|
|
|
this.index.version = Math.max(4, this.index.version); // v4 is required for byterange support
|
|
|
this.index.version = Math.max(2, this.index.version); // v2 is required to support the remapped IV attribute
|
|
|
@@ -77,45 +77,39 @@ HlsStreamRecorder.prototype.updateIndex = function(update) {
|
|
|
this.index.start.decimalInteger('time-offset', offset);
|
|
|
}
|
|
|
} else {
|
|
|
- debug('programs', this.index.programs);
|
|
|
+ debug('variants', this.index.variants);
|
|
|
if (this.subreader) {
|
|
|
- var programNo = Object.keys(this.index.programs)[0];
|
|
|
- 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);
|
|
|
+ let used = {};
|
|
|
+ this.index.variants = this.index.variants.filter((variant) => {
|
|
|
+ let bw = parseInt(variant.info.bandwidth, 10);
|
|
|
+ let 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);
|
|
|
+ this.index.variants.forEach((variant, index) => {
|
|
|
+ var variantUrl = url.resolve(self.reader.baseUrl, variant.uri);
|
|
|
+ debug('url', variantUrl);
|
|
|
|
|
|
// check for duplicate source urls
|
|
|
- var rec = this.recorderForUrl(programUrl);
|
|
|
+ var rec = this.recorderForUrl(variantUrl);
|
|
|
if (!rec || !rec.localUrl) {
|
|
|
- var dir = self.variantName(program.info, index);
|
|
|
- rec = new HlsStreamRecorder(self.subreader(programUrl), path.join(self.dst, dir), { startOffset: self.startOffset, collect: self.collect, decrypt: this.decrypt });
|
|
|
+ var dir = self.variantName(variant.info, index);
|
|
|
+ rec = new HlsStreamRecorder(self.subreader(variantUrl), path.join(self.dst, dir), { startOffset: self.startOffset, collect: self.collect, decrypt: this.decrypt });
|
|
|
rec.localUrl = url.format({pathname: path.join(dir, 'index.m3u8')});
|
|
|
- rec.remoteUrl = programUrl;
|
|
|
+ rec.remoteUrl = variantUrl;
|
|
|
|
|
|
this.recorders.push(rec);
|
|
|
}
|
|
|
|
|
|
- program.uri = rec.localUrl;
|
|
|
- }, this);
|
|
|
+ variant.uri = rec.localUrl;
|
|
|
+ });
|
|
|
|
|
|
var allGroups = [];
|
|
|
for (var group in this.index.groups)
|
|
|
[].push.apply(allGroups, this.index.groups[group]);
|
|
|
|
|
|
-
|
|
|
allGroups.forEach(function(groupItem, index) {
|
|
|
var srcUri = groupItem.quotedString('uri');
|
|
|
if (srcUri) {
|
|
|
@@ -141,11 +135,11 @@ HlsStreamRecorder.prototype.updateIndex = function(update) {
|
|
|
recording.start();
|
|
|
});
|
|
|
|
|
|
- this.index.iframes = {};
|
|
|
+ this.index.iframes = [];
|
|
|
} else {
|
|
|
- this.index.programs = {};
|
|
|
+ this.index.variants = [];
|
|
|
this.index.groups = {};
|
|
|
- this.index.iframes = {};
|
|
|
+ this.index.iframes = [];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -170,7 +164,7 @@ HlsStreamRecorder.prototype.updateIndex = function(update) {
|
|
|
HlsStreamRecorder.prototype.process = function(segmentInfo, done) {
|
|
|
var self = this;
|
|
|
|
|
|
- var segment = new m3u8parse.M3U8Segment(segmentInfo.details, true);
|
|
|
+ var segment = new M3U8Parse.M3U8Segment(segmentInfo.details, true);
|
|
|
var meta = segmentInfo.file;
|
|
|
|
|
|
// mark discontinuities
|
|
|
@@ -195,12 +189,12 @@ HlsStreamRecorder.prototype.process = function(segmentInfo, done) {
|
|
|
}
|
|
|
|
|
|
// save the stream segment
|
|
|
- SegmentDecrypt.decrypt(segmentInfo.stream, segmentInfo.details.key, this.decrypt, function (err, stream, decrypted) {
|
|
|
+ SegmentDecrypt.decrypt(segmentInfo.stream, segmentInfo.details.keys, this.decrypt, function (err, stream, decrypted) {
|
|
|
if (err) {
|
|
|
console.error('decrypt failed', err.stack);
|
|
|
stream = segmentInfo.stream;
|
|
|
} else if (decrypted) {
|
|
|
- segment.key = null;
|
|
|
+ segment.keys = null;
|
|
|
}
|
|
|
|
|
|
stream = oncemore(stream);
|