eyevinn-channel-engine 4.0.7 → 4.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,6 +58,7 @@ export interface ChannelProfile {
58
58
  bw: number;
59
59
  codecs: string;
60
60
  resolution: number[];
61
+ channels?: string;
61
62
  }
62
63
  export interface Channel {
63
64
  id: string;
@@ -75,8 +76,6 @@ export interface ClosedCaptions {
75
76
  export interface AudioTracks {
76
77
  language: string;
77
78
  name: string;
78
- channels?: number;
79
- codecs?: string;
80
79
  default?: boolean;
81
80
  }
82
81
  export interface IChannelManager {
@@ -43,7 +43,7 @@ var HLSTruncateVod = require('@eyevinn/hls-truncate');
43
43
  var Readable = require('stream').Readable;
44
44
  var SessionState = require('./session_state.js').SessionState;
45
45
  var PlayheadState = require('./playhead_state.js').PlayheadState;
46
- var _a = require('./util.js'), applyFilter = _a.applyFilter, cloudWatchLog = _a.cloudWatchLog, m3u8Header = _a.m3u8Header, logerror = _a.logerror;
46
+ var _a = require('./util.js'), applyFilter = _a.applyFilter, cloudWatchLog = _a.cloudWatchLog, m3u8Header = _a.m3u8Header, logerror = _a.logerror, codecsFromString = _a.codecsFromString;
47
47
  var ChaosMonkey = require('./chaos_monkey.js');
48
48
  var AVERAGE_SEGMENT_DURATION = 3000;
49
49
  var DEFAULT_PLAYHEAD_DIFF_THRESHOLD = 1000;
@@ -923,7 +923,7 @@ var Session = /** @class */ (function () {
923
923
  debug("[".concat(this._sessionId, "]: {").concat(mediaSequenceValue, "}_{").concat(currentVod.getLastSequenceMediaSequenceValueAudio(), "} AUDIO"));
924
924
  manifestMseq = playheadState.mediaSeqAudio + mediaSequenceValue;
925
925
  }
926
- debug("[".concat(this._sessionId, "]: [").concat(playheadState.vodMediaSeqAudio, "]_[").concat(currentVod.getLiveMediaSequencesCount("audio"), "] AUDIO"));
926
+ debug("[".concat(this._sessionId, "]: [").concat(playheadState.vodMediaSeqAudio, "]_[").concat(currentVod.getLiveMediaSequencesCount("audio"), "] AUDIO (").concat(audioGroupId, ")"));
927
927
  m3u8_2 = currentVod.getLiveMediaAudioSequences(playheadState.mediaSeqAudio, audioGroupId, audioLanguage, playheadState.vodMediaSeqAudio, sessionState.discSeqAudio, this.targetDurationPadding, this.forceTargetDuration);
928
928
  // # Case: current VOD does not have the selected track.
929
929
  if (!m3u8_2) {
@@ -1346,10 +1346,10 @@ var Session = /** @class */ (function () {
1346
1346
  };
1347
1347
  Session.prototype.getMasterManifestAsync = function (filter) {
1348
1348
  return __awaiter(this, void 0, void 0, function () {
1349
- var m3u8, currentVod, audioGroupIds, defaultAudioGroupId, hasClosedCaptions, i, audioGroupId, j, audioTrack, channels, sessionProfile;
1349
+ var m3u8, currentVod, audioGroupIds, defaultAudioGroupId, hasClosedCaptions, i, audioGroupId, j, audioTrack, _a, _, channels, sessionProfile;
1350
1350
  var _this = this;
1351
- return __generator(this, function (_a) {
1352
- switch (_a.label) {
1351
+ return __generator(this, function (_b) {
1352
+ switch (_b.label) {
1353
1353
  case 0:
1354
1354
  m3u8 = "#EXTM3U\n";
1355
1355
  m3u8 += "#EXT-X-VERSION:4\n";
@@ -1360,7 +1360,7 @@ var Session = /** @class */ (function () {
1360
1360
  }
1361
1361
  return [4 /*yield*/, this._sessionState.getCurrentVod()];
1362
1362
  case 1:
1363
- currentVod = _a.sent();
1363
+ currentVod = _b.sent();
1364
1364
  if (!currentVod) {
1365
1365
  throw new Error('Session not ready');
1366
1366
  }
@@ -1378,14 +1378,16 @@ var Session = /** @class */ (function () {
1378
1378
  audioGroupId = audioGroupIds[i];
1379
1379
  for (j = 0; j < this._audioTracks.length; j++) {
1380
1380
  audioTrack = this._audioTracks[j];
1381
- channels = this._audioTracks[j].channels ? this._audioTracks[j].channels : 2;
1381
+ _a = currentVod.getAudioCodecsAndChannelsForGroupId(audioGroupId), _ = _a[0], channels = _a[1];
1382
1382
  // Make default track if set property is true.
1383
- if (audioTrack.default) {
1384
- m3u8 += "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"".concat(audioGroupId, "\",LANGUAGE=\"").concat(audioTrack.language, "\", NAME=\"").concat(audioTrack.name, "\",AUTOSELECT=YES,DEFAULT=YES,CHANNELS=\"").concat(channels, "\",URI=\"master-").concat(audioGroupId, "_").concat(audioTrack.language, ".m3u8;session=").concat(this._sessionId, "\"\n");
1385
- }
1386
- else {
1387
- m3u8 += "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"".concat(audioGroupId, "\",LANGUAGE=\"").concat(audioTrack.language, "\", NAME=\"").concat(audioTrack.name, "\",AUTOSELECT=YES,DEFAULT=NO,CHANNELS=\"").concat(channels, "\",URI=\"master-").concat(audioGroupId, "_").concat(audioTrack.language, ".m3u8;session=").concat(this._sessionId, "\"\n");
1388
- }
1383
+ m3u8 += "#EXT-X-MEDIA:TYPE=AUDIO" +
1384
+ ",GROUP-ID=\"".concat(audioGroupId, "\"") +
1385
+ ",LANGUAGE=\"".concat(audioTrack.language, "\"") +
1386
+ ",NAME=\"".concat(audioTrack.name, "\"") +
1387
+ ",AUTOSELECT=YES,DEFAULT=".concat(audioTrack.default ? 'YES' : 'NO') +
1388
+ ",CHANNELS=\"".concat(channels ? channels : 2, "\"") +
1389
+ ",URI=\"master-".concat(audioGroupId, "_").concat(audioTrack.language, ".m3u8;session=").concat(this._sessionId, "\"") +
1390
+ "\n";
1389
1391
  }
1390
1392
  }
1391
1393
  // As of now, by default set StreamItem's AUDIO attribute to <first audio group-id>
@@ -1395,13 +1397,41 @@ var Session = /** @class */ (function () {
1395
1397
  if (this._sessionProfile) {
1396
1398
  sessionProfile = filter ? applyFilter(this._sessionProfile, filter) : this._sessionProfile;
1397
1399
  sessionProfile.forEach(function (profile) {
1398
- m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw + ',RESOLUTION=' + profile.resolution[0] + 'x' + profile.resolution[1] + ',CODECS="' + profile.codecs + '"' + (defaultAudioGroupId ? ",AUDIO=\"".concat(defaultAudioGroupId, "\"") : '') + (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
1399
- m3u8 += "master" + profile.bw + ".m3u8;session=" + _this._sessionId + "\n";
1400
+ if (_this.use_demuxed_audio) {
1401
+ // find matching audio group based on codec in stream
1402
+ var audioGroupIdToUse = void 0;
1403
+ var _a = codecsFromString(profile.codecs), _ = _a[0], audioCodec = _a[1];
1404
+ if (audioCodec) {
1405
+ var profileChannels = profile.channels ? profile.channels : "2";
1406
+ audioGroupIdToUse = currentVod.getAudioGroupIdForCodecs(audioCodec, profileChannels);
1407
+ }
1408
+ // skip stream if no corresponding audio group can be found
1409
+ if (audioGroupIdToUse) {
1410
+ m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw +
1411
+ ',RESOLUTION=' + profile.resolution[0] + 'x' + profile.resolution[1] +
1412
+ ',CODECS="' + profile.codecs + '"' +
1413
+ ",AUDIO=\"".concat(audioGroupIdToUse, "\"") +
1414
+ (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
1415
+ m3u8 += "master" + profile.bw + ".m3u8;session=" + _this._sessionId + "\n";
1416
+ }
1417
+ }
1418
+ else {
1419
+ m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw +
1420
+ ',RESOLUTION=' + profile.resolution[0] + 'x' + profile.resolution[1] +
1421
+ ',CODECS="' + profile.codecs + '"' +
1422
+ (defaultAudioGroupId ? ",AUDIO=\"".concat(defaultAudioGroupId, "\"") : '') +
1423
+ (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
1424
+ m3u8 += "master" + profile.bw + ".m3u8;session=" + _this._sessionId + "\n";
1425
+ }
1400
1426
  });
1401
1427
  }
1402
1428
  else {
1403
1429
  currentVod.getUsageProfiles().forEach(function (profile) {
1404
- m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw + ',RESOLUTION=' + profile.resolution + ',CODECS="' + profile.codecs + '"' + (defaultAudioGroupId ? ",AUDIO=\"".concat(defaultAudioGroupId, "\"") : '') + (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
1430
+ m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw +
1431
+ ',RESOLUTION=' + profile.resolution +
1432
+ ',CODECS="' + profile.codecs + '"' +
1433
+ (defaultAudioGroupId ? ",AUDIO=\"".concat(defaultAudioGroupId, "\"") : '') +
1434
+ (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
1405
1435
  m3u8 += "master" + profile.bw + ".m3u8;session=" + _this._sessionId + "\n";
1406
1436
  });
1407
1437
  }
@@ -17,3 +17,4 @@ export class WaitTimeGenerator {
17
17
  export function findNearestValue(val: any, array: any): any;
18
18
  export function isValidUrl(url: any): boolean;
19
19
  export function fetchWithRetry(uri: any, opts: any, maxRetries: any, retryDelayMs: any, timeoutMs: any, debug: any): Promise<any>;
20
+ export function codecsFromString(codecs: any): any[];
@@ -266,6 +266,15 @@ var fetchWithRetry = function (uri, opts, maxRetries, retryDelayMs, timeoutMs, d
266
266
  }
267
267
  });
268
268
  }); };
269
+ var codecsFromString = function (codecs) {
270
+ var audioCodecs = codecs.split(",").find(function (c) {
271
+ return c.match(/^mp4a/) || c.match(/^ac-3/) || c.match(/^ec-3/);
272
+ });
273
+ var videoCodecs = codecs.split(",").find(function (c) {
274
+ return c.match(/^avc/) || c.match(/^hevc/) || c.match(/^dvh/);
275
+ });
276
+ return [videoCodecs, audioCodecs];
277
+ };
269
278
  module.exports = {
270
279
  filterQueryParser: filterQueryParser,
271
280
  applyFilter: applyFilter,
@@ -277,5 +286,6 @@ module.exports = {
277
286
  WaitTimeGenerator: WaitTimeGenerator,
278
287
  findNearestValue: findNearestValue,
279
288
  isValidUrl: isValidUrl,
280
- fetchWithRetry: fetchWithRetry
289
+ fetchWithRetry: fetchWithRetry,
290
+ codecsFromString: codecsFromString
281
291
  };
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "4.0.7",
3
+ "version": "4.0.8",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  "dependencies": {
27
27
  "@eyevinn/hls-repeat": "^0.2.0",
28
28
  "@eyevinn/hls-truncate": "^0.2.0",
29
- "@eyevinn/hls-vodtolive": "^2.2.1",
29
+ "@eyevinn/hls-vodtolive": "^2.3.3",
30
30
  "@eyevinn/m3u8": "^0.5.3",
31
31
  "abort-controller": "^3.0.0",
32
32
  "debug": "^3.2.7",
@@ -81,8 +81,8 @@ var RefChannelManager = /** @class */ (function () {
81
81
  };
82
82
  RefChannelManager.prototype._getAudioTracks = function () {
83
83
  return [
84
- { language: "en", name: "English" },
85
- { language: "sp", name: "Spanish" }
84
+ { language: "en", name: "English", default: true },
85
+ { language: "sp", name: "Spanish", default: false }
86
86
  ];
87
87
  };
88
88
  return RefChannelManager;
@@ -65,18 +65,18 @@ var RefChannelManager = /** @class */ (function () {
65
65
  };
66
66
  RefChannelManager.prototype._getProfile = function () {
67
67
  return [
68
- { resolution: [640, 360], bw: 3663471, codecs: "avc1.64001F,mp4a.40.2" },
69
- { resolution: [1280, 720], bw: 5841380, codecs: "avc1.64001F,mp4a.40.2" },
70
- { resolution: [1920, 1080], bw: 8973571, codecs: "avc1.64001F,mp4a.40.2" },
71
- { resolution: [640, 360], bw: 4301519, codecs: "avc1.64001F,ec-3" },
72
- { resolution: [1280, 720], bw: 6479428, codecs: "avc1.64001F,ec-3" },
73
- { resolution: [1920, 1080], bw: 9611619, codecs: "avc1.640032,ec-3" },
68
+ { resolution: [640, 360], bw: 3663471, codecs: "avc1.64001F,mp4a.40.2", channels: "2" },
69
+ { resolution: [1280, 720], bw: 5841380, codecs: "avc1.64001F,mp4a.40.2", channels: "2" },
70
+ { resolution: [1920, 1080], bw: 8973571, codecs: "avc1.64001F,mp4a.40.2", channels: "2" },
71
+ { resolution: [640, 360], bw: 4301519, codecs: "avc1.64001F,ec-3", channels: "16/JOC" },
72
+ { resolution: [1280, 720], bw: 6479428, codecs: "avc1.64001F,ec-3", channels: "16/JOC" },
73
+ { resolution: [1920, 1080], bw: 9611619, codecs: "avc1.640032,ec-3", channels: "16/JOC" },
74
74
  ];
75
75
  };
76
76
  RefChannelManager.prototype._getAudioTracks = function () {
77
77
  return [
78
- { language: "ja", "name": "日本語 stereo", channels: 2, codecs: "mp4a.40.2", default: true },
79
- { language: "ja", "name": "日本語 surround", channels: 16, codecs: "ec-3", default: false }
78
+ { language: "ja", "name": "日本語", default: true },
79
+ { language: "en", "name": "English", default: false }
80
80
  ];
81
81
  };
82
82
  return RefChannelManager;
package/engine/server.ts CHANGED
@@ -99,6 +99,7 @@ export interface ChannelProfile {
99
99
  bw: number;
100
100
  codecs: string;
101
101
  resolution: number[];
102
+ channels?: string;
102
103
  }
103
104
 
104
105
  export interface Channel {
@@ -119,8 +120,6 @@ export interface ClosedCaptions {
119
120
  export interface AudioTracks {
120
121
  language: string;
121
122
  name: string;
122
- channels?: number;
123
- codecs?: string;
124
123
  default?: boolean;
125
124
  }
126
125
 
package/engine/session.js CHANGED
@@ -9,7 +9,7 @@ const Readable = require('stream').Readable;
9
9
  const { SessionState } = require('./session_state.js');
10
10
  const { PlayheadState } = require('./playhead_state.js');
11
11
 
12
- const { applyFilter, cloudWatchLog, m3u8Header, logerror } = require('./util.js');
12
+ const { applyFilter, cloudWatchLog, m3u8Header, logerror, codecsFromString } = require('./util.js');
13
13
  const ChaosMonkey = require('./chaos_monkey.js');
14
14
 
15
15
  const AVERAGE_SEGMENT_DURATION = 3000;
@@ -655,7 +655,7 @@ class Session {
655
655
  debug(`[${this._sessionId}]: {${mediaSequenceValue}}_{${currentVod.getLastSequenceMediaSequenceValueAudio()}} AUDIO`);
656
656
  manifestMseq = playheadState.mediaSeqAudio + mediaSequenceValue;
657
657
  }
658
- debug(`[${this._sessionId}]: [${playheadState.vodMediaSeqAudio}]_[${currentVod.getLiveMediaSequencesCount("audio")}] AUDIO`);
658
+ debug(`[${this._sessionId}]: [${playheadState.vodMediaSeqAudio}]_[${currentVod.getLiveMediaSequencesCount("audio")}] AUDIO (${audioGroupId})`);
659
659
  const m3u8 = currentVod.getLiveMediaAudioSequences(
660
660
  playheadState.mediaSeqAudio,
661
661
  audioGroupId,
@@ -959,13 +959,16 @@ class Session {
959
959
  let audioGroupId = audioGroupIds[i];
960
960
  for (let j = 0; j < this._audioTracks.length; j++) {
961
961
  let audioTrack = this._audioTracks[j];
962
- let channels = this._audioTracks[j].channels ? this._audioTracks[j].channels : 2;
962
+ const [_, channels] = currentVod.getAudioCodecsAndChannelsForGroupId(audioGroupId);
963
963
  // Make default track if set property is true.
964
- if (audioTrack.default) {
965
- m3u8 += `#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="${audioGroupId}",LANGUAGE="${audioTrack.language}", NAME="${audioTrack.name}",AUTOSELECT=YES,DEFAULT=YES,CHANNELS="${channels}",URI="master-${audioGroupId}_${audioTrack.language}.m3u8;session=${this._sessionId}"\n`;
966
- } else {
967
- m3u8 += `#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="${audioGroupId}",LANGUAGE="${audioTrack.language}", NAME="${audioTrack.name}",AUTOSELECT=YES,DEFAULT=NO,CHANNELS="${channels}",URI="master-${audioGroupId}_${audioTrack.language}.m3u8;session=${this._sessionId}"\n`;
968
- }
964
+ m3u8 += `#EXT-X-MEDIA:TYPE=AUDIO` +
965
+ `,GROUP-ID="${audioGroupId}"` +
966
+ `,LANGUAGE="${audioTrack.language}"` +
967
+ `,NAME="${audioTrack.name}"` +
968
+ `,AUTOSELECT=YES,DEFAULT=${audioTrack.default ? 'YES' : 'NO'}` +
969
+ `,CHANNELS="${channels ? channels : 2}"` +
970
+ `,URI="master-${audioGroupId}_${audioTrack.language}.m3u8;session=${this._sessionId}"` +
971
+ "\n";
969
972
  }
970
973
  }
971
974
  // As of now, by default set StreamItem's AUDIO attribute to <first audio group-id>
@@ -975,12 +978,40 @@ class Session {
975
978
  if (this._sessionProfile) {
976
979
  const sessionProfile = filter ? applyFilter(this._sessionProfile, filter) : this._sessionProfile;
977
980
  sessionProfile.forEach(profile => {
978
- m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw + ',RESOLUTION=' + profile.resolution[0] + 'x' + profile.resolution[1] + ',CODECS="' + profile.codecs + '"' + (defaultAudioGroupId ? `,AUDIO="${defaultAudioGroupId}"` : '') + (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
979
- m3u8 += "master" + profile.bw + ".m3u8;session=" + this._sessionId + "\n";
981
+ if (this.use_demuxed_audio) {
982
+ // find matching audio group based on codec in stream
983
+ let audioGroupIdToUse;
984
+ const [_, audioCodec] = codecsFromString(profile.codecs);
985
+ if (audioCodec) {
986
+ const profileChannels = profile.channels ? profile.channels : "2";
987
+ audioGroupIdToUse = currentVod.getAudioGroupIdForCodecs(audioCodec, profileChannels);
988
+ }
989
+
990
+ // skip stream if no corresponding audio group can be found
991
+ if (audioGroupIdToUse) {
992
+ m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw +
993
+ ',RESOLUTION=' + profile.resolution[0] + 'x' + profile.resolution[1] +
994
+ ',CODECS="' + profile.codecs + '"' +
995
+ `,AUDIO="${audioGroupIdToUse}"` +
996
+ (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
997
+ m3u8 += "master" + profile.bw + ".m3u8;session=" + this._sessionId + "\n";
998
+ }
999
+ } else {
1000
+ m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw +
1001
+ ',RESOLUTION=' + profile.resolution[0] + 'x' + profile.resolution[1] +
1002
+ ',CODECS="' + profile.codecs + '"' +
1003
+ (defaultAudioGroupId ? `,AUDIO="${defaultAudioGroupId}"` : '') +
1004
+ (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
1005
+ m3u8 += "master" + profile.bw + ".m3u8;session=" + this._sessionId + "\n";
1006
+ }
980
1007
  });
981
1008
  } else {
982
1009
  currentVod.getUsageProfiles().forEach(profile => {
983
- m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw + ',RESOLUTION=' + profile.resolution + ',CODECS="' + profile.codecs + '"' + (defaultAudioGroupId ? `,AUDIO="${defaultAudioGroupId}"` : '') + (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
1010
+ m3u8 += '#EXT-X-STREAM-INF:BANDWIDTH=' + profile.bw +
1011
+ ',RESOLUTION=' + profile.resolution +
1012
+ ',CODECS="' + profile.codecs + '"' +
1013
+ (defaultAudioGroupId ? `,AUDIO="${defaultAudioGroupId}"` : '') +
1014
+ (hasClosedCaptions ? ',CLOSED-CAPTIONS="cc"' : '') + '\n';
984
1015
  m3u8 += "master" + profile.bw + ".m3u8;session=" + this._sessionId + "\n";
985
1016
  });
986
1017
  }
package/engine/util.js CHANGED
@@ -214,6 +214,16 @@ const fetchWithRetry = async (uri, opts, maxRetries, retryDelayMs, timeoutMs, de
214
214
  }
215
215
  };
216
216
 
217
+ const codecsFromString = (codecs) => {
218
+ const audioCodecs = codecs.split(",").find(c => {
219
+ return c.match(/^mp4a/) || c.match(/^ac-3/) || c.match(/^ec-3/);
220
+ });
221
+ const videoCodecs = codecs.split(",").find(c => {
222
+ return c.match(/^avc/) || c.match(/^hevc/) || c.match(/^dvh/);
223
+ });
224
+ return [videoCodecs, audioCodecs];
225
+ };
226
+
217
227
  module.exports = {
218
228
  filterQueryParser,
219
229
  applyFilter,
@@ -225,5 +235,6 @@ module.exports = {
225
235
  WaitTimeGenerator,
226
236
  findNearestValue,
227
237
  isValidUrl,
228
- fetchWithRetry
238
+ fetchWithRetry,
239
+ codecsFromString
229
240
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "4.0.7",
3
+ "version": "4.0.8",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  "dependencies": {
27
27
  "@eyevinn/hls-repeat": "^0.2.0",
28
28
  "@eyevinn/hls-truncate": "^0.2.0",
29
- "@eyevinn/hls-vodtolive": "^2.2.1",
29
+ "@eyevinn/hls-vodtolive": "^2.3.3",
30
30
  "@eyevinn/m3u8": "^0.5.3",
31
31
  "abort-controller": "^3.0.0",
32
32
  "debug": "^3.2.7",
package/server-demux.ts CHANGED
@@ -91,8 +91,8 @@ class RefChannelManager implements IChannelManager {
91
91
  }
92
92
  _getAudioTracks(): AudioTracks[] {
93
93
  return [
94
- { language: "en", name: "English" },
95
- { language: "sp", name: "Spanish" }
94
+ { language: "en", name: "English", default: true },
95
+ { language: "sp", name: "Spanish", default: false }
96
96
  ];
97
97
  }
98
98
  }
@@ -69,20 +69,20 @@ class RefChannelManager implements IChannelManager {
69
69
 
70
70
  _getProfile(): ChannelProfile[] {
71
71
  return [
72
- { resolution: [640, 360], bw: 3663471, codecs: "avc1.64001F,mp4a.40.2" },
73
- { resolution: [1280, 720], bw: 5841380, codecs: "avc1.64001F,mp4a.40.2" },
74
- { resolution: [1920, 1080], bw: 8973571, codecs: "avc1.64001F,mp4a.40.2" },
72
+ { resolution: [640, 360], bw: 3663471, codecs: "avc1.64001F,mp4a.40.2", channels: "2" },
73
+ { resolution: [1280, 720], bw: 5841380, codecs: "avc1.64001F,mp4a.40.2", channels: "2" },
74
+ { resolution: [1920, 1080], bw: 8973571, codecs: "avc1.64001F,mp4a.40.2", channels: "2" },
75
75
 
76
- { resolution: [640, 360], bw: 4301519, codecs: "avc1.64001F,ec-3" },
77
- { resolution: [1280, 720], bw: 6479428, codecs: "avc1.64001F,ec-3" },
78
- { resolution: [1920, 1080], bw: 9611619, codecs: "avc1.640032,ec-3" },
76
+ { resolution: [640, 360], bw: 4301519, codecs: "avc1.64001F,ec-3", channels: "16/JOC" },
77
+ { resolution: [1280, 720], bw: 6479428, codecs: "avc1.64001F,ec-3", channels: "16/JOC" },
78
+ { resolution: [1920, 1080], bw: 9611619, codecs: "avc1.640032,ec-3", channels: "16/JOC" },
79
79
  ];
80
80
  }
81
81
 
82
82
  _getAudioTracks(): AudioTracks[] {
83
83
  return [
84
- { language: "ja", "name": "日本語 stereo", channels: 2, codecs: "mp4a.40.2", default: true },
85
- { language: "ja", "name": "日本語 surround", channels: 16, codecs: "ec-3", default: false }
84
+ { language: "ja", "name": "日本語", default: true },
85
+ { language: "en", "name": "English", default: false }
86
86
  ];
87
87
  }
88
88
  }
@@ -101,4 +101,4 @@ const engineOptions: ChannelEngineOpts = {
101
101
 
102
102
  const engine = new ChannelEngine(refAssetManager, engineOptions);
103
103
  engine.start();
104
- engine.listen(process.env.PORT || 8000);
104
+ engine.listen(process.env.PORT || 8000);