eyevinn-channel-engine 5.0.0 → 5.0.3

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.
@@ -431,7 +431,6 @@ var ChannelEngine = /** @class */ (function () {
431
431
  case 0:
432
432
  debug("Do we have any new channels?");
433
433
  newChannels = channelMgr.getChannels().filter(function (channel) { return !sessions[channel.id]; });
434
- debug(JSON.stringify(newChannels));
435
434
  addAsync = function (channel) { return __awaiter(_this, void 0, void 0, function () {
436
435
  var _this = this;
437
436
  return __generator(this, function (_a) {
@@ -138,4 +138,5 @@ declare class Session {
138
138
  _getM3u8File(variantType: any, variantKey: any, playbackSessionId: any): Promise<any>;
139
139
  _getCurrentVodData(dataName: any, variantType: any, vod: any): any;
140
140
  _logCurrentPlayheadPositions(playheadPosVideoMs: any, playheadAudio: any, playheadSubtitle: any): void;
141
+ _logAllPlayheadPositions: (sessionId: any, vod: any) => void;
141
142
  }
@@ -70,6 +70,23 @@ var Session = /** @class */ (function () {
70
70
  *
71
71
  */
72
72
  function Session(assetManager, config, sessionStore) {
73
+ this._logAllPlayheadPositions = function (sessionId, vod) {
74
+ if (!vod) {
75
+ return;
76
+ }
77
+ if (!vod.getPlayheadPositions) {
78
+ return;
79
+ }
80
+ if (vod.getPlayheadPositions("video")) {
81
+ debug("[".concat(sessionId, "]: playhead positions [V]=").concat(vod.getPlayheadPositions("video").map(roundToThreeDecimals).join(",")));
82
+ }
83
+ if (vod.getPlayheadPositions("audio")) {
84
+ debug("[".concat(sessionId, "]: playhead positions [A]=").concat(vod.getPlayheadPositions("audio").map(roundToThreeDecimals).join(",")));
85
+ }
86
+ if (vod.getPlayheadPositions("subtitle")) {
87
+ debug("[".concat(sessionId, "]: playhead positions [S]=").concat(vod.getPlayheadPositions("subtitle").map(roundToThreeDecimals).join(",")));
88
+ }
89
+ };
73
90
  this._assetManager = assetManager;
74
91
  this._sessionId = crypto.randomBytes(20).toString('hex');
75
92
  this._sessionStateStore = sessionStore.sessionStateStore;
@@ -365,7 +382,7 @@ var Session = /** @class */ (function () {
365
382
  }
366
383
  }
367
384
  else {
368
- console.warn("[".concat(this._sessionId, "]: Playhead tick interval went over Max tick interval by ").concat(changeMaxTick, "ms.\n If the value keeps increasing, consider increasing the 'maxTickInterval' in engineOptions"));
385
+ debug("[".concat(this._sessionId, "]: Playhead tick interval went over Max tick interval by ").concat(changeMaxTick, "ms.\n If the value keeps increasing, consider increasing the 'maxTickInterval' in engineOptions"));
369
386
  }
370
387
  tickInterval = this.maxTickInterval / 1000;
371
388
  }
@@ -1777,11 +1794,8 @@ var Session = /** @class */ (function () {
1777
1794
  case 17:
1778
1795
  _u.sent();
1779
1796
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'loadVod', channel: this._sessionId, loadTimeMs: Date.now() - loadStart });
1780
- debug("[".concat(this._sessionId, "]: first VOD loaded"));
1781
- debug("[".concat(this._sessionId, "]: ").concat(currentVod.getDeltaTimes()));
1782
- debug("[".concat(this._sessionId, "]: playhead positions [V]=").concat(currentVod.getPlayheadPositions("video")));
1783
- debug("[".concat(this._sessionId, "]: playhead positions [A]=").concat(currentVod.getPlayheadPositions("audio")));
1784
- debug("[".concat(this._sessionId, "]: playhead positions [S]=").concat(currentVod.getPlayheadPositions("subtitle")));
1797
+ debug("[".concat(this._sessionId, "]: first VOD loaded. DeltaTimes ").concat(currentVod.getDeltaTimes().map(roundToThreeDecimals).join(",")));
1798
+ this._logAllPlayheadPositions(this._sessionId, currentVod);
1785
1799
  return [4 /*yield*/, this._sessionState.setValues({
1786
1800
  "mediaSeq": 0,
1787
1801
  "mediaSeqAudio": 0,
@@ -2029,10 +2043,8 @@ var Session = /** @class */ (function () {
2029
2043
  _u.sent();
2030
2044
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session', { event: 'loadVod', channel: this._sessionId, loadTimeMs: Date.now() - loadStart });
2031
2045
  this.leaderIsSettingNextVod = true;
2032
- debug("[".concat(this._sessionId, "]: next VOD loaded (").concat(newVod.getDeltaTimes(), ")"));
2033
- debug("[".concat(this._sessionId, "]: playhead positions [V]=").concat(newVod.getPlayheadPositions("video")));
2034
- debug("[".concat(this._sessionId, "]: playhead positions [A]=").concat(newVod.getPlayheadPositions("audio")));
2035
- debug("[".concat(this._sessionId, "]: playhead positions [S]=").concat(newVod.getPlayheadPositions("subtitle")));
2046
+ debug("[".concat(this._sessionId, "]: next VOD loaded (").concat(newVod.getDeltaTimes().map(roundToThreeDecimals).join(","), ")"));
2047
+ this._logAllPlayheadPositions(this._sessionId, newVod);
2036
2048
  currentVod = newVod;
2037
2049
  debug("[".concat(this._sessionId, "]: msequences=").concat(currentVod.getLiveMediaSequencesCount(), "; audio msequences=").concat(currentVod.getLiveMediaSequencesCount("audio"), "; subtitle msequences=").concat(currentVod.getLiveMediaSequencesCount("subtitle")));
2038
2050
  _m = sessionState;
@@ -21,7 +21,7 @@ export function fetchWithRetry(uri: any, opts: any, maxRetries: any, retryDelayM
21
21
  export function codecsFromString(codecs: any): any[];
22
22
  export function timeLeft(endTimestamp: any, currentTimestamp: any): string;
23
23
  export function findAudioGroupOrLang(val: any, array: any): any;
24
- export function roundToThreeDecimals(number: any): number;
24
+ export function roundToThreeDecimals(number: any): any;
25
25
  export const COMMON_HEADERS: {
26
26
  "Content-Type": string;
27
27
  "Access-Control-Allow-Origin": string;
@@ -309,6 +309,15 @@ var timeLeft = function (endTimestamp, currentTimestamp) {
309
309
  return msg;
310
310
  };
311
311
  var roundToThreeDecimals = function (number) {
312
+ if (typeof number !== "number") {
313
+ try {
314
+ number = parseFloat(number);
315
+ }
316
+ catch (e) {
317
+ console.error("Could not convert to number:", number);
318
+ return number;
319
+ }
320
+ }
312
321
  var r = Math.round(number * 1000) / 1000;
313
322
  return r;
314
323
  };
@@ -8,8 +8,8 @@ var uuidv4 = require('uuid').v4;
8
8
  var DEMUX_CONTENT = {
9
9
  TS: {
10
10
  slate: "https://testcontent.eyevinn.technology/ce_test_content/DEMUX_VINJETTE_TS_001/master.m3u8",
11
- vod: "https://testcontent.eyevinn.technology/ce_test_content/DEMUX_VOD_TS_001/master.m3u8",
12
- trailer: "https://testcontent.eyevinn.technology/ce_test_content/DEMUX_TRAILER_TS_001/index.m3u8",
11
+ vod: "https://maitv-vod.lab.eyevinn.technology/VINN.mp4/master_demux.m3u8",
12
+ trailer: "https://maitv-vod.lab.eyevinn.technology/ads/apotea-15s.mp4/master_demux.m3u8",
13
13
  bumper: "https://testcontent.eyevinn.technology/ce_test_content/DEMUX_VINJETTE_TS_001/master.m3u8",
14
14
  // If you do not have a demux live stream available, you can always use a local CE V2L stream (ex: demux.ts)
15
15
  live: null
@@ -23,7 +23,7 @@ var DEMUX_CONTENT = {
23
23
  live: null
24
24
  }
25
25
  };
26
- var HLS_CONTENT = DEMUX_CONTENT.CMAF;
26
+ var HLS_CONTENT = DEMUX_CONTENT.TS;
27
27
  var FIRST_PLAYED_VOD = true;
28
28
  var CONFIGS = {
29
29
  USE_STITCHER: 0,
@@ -86,13 +86,13 @@ var RefAssetManager = /** @class */ (function () {
86
86
  resolve(vodResponse);
87
87
  }
88
88
  else {
89
- FIRST_PLAYED_VOD = false;
90
89
  var vodResponse = {
91
90
  id: vod.id,
92
91
  title: vod.title,
93
92
  uri: vod.uri,
94
93
  unixTs: unixTs
95
94
  };
95
+ FIRST_PLAYED_VOD = false;
96
96
  resolve(vodResponse);
97
97
  }
98
98
  }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "5.0.0",
3
+ "version": "5.0.3",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,8 +30,8 @@
30
30
  "license": "Apache-2.0",
31
31
  "dependencies": {
32
32
  "@eyevinn/hls-repeat": "^0.2.1",
33
- "@eyevinn/hls-truncate": "^0.3.1",
34
- "@eyevinn/hls-vodtolive": "^4.1.5",
33
+ "@eyevinn/hls-truncate": "^0.3.3",
34
+ "@eyevinn/hls-vodtolive": "^4.1.7",
35
35
  "@eyevinn/m3u8": "^0.5.6",
36
36
  "@fastify/static": "^5.0.0",
37
37
  "abort-controller": "^3.0.0",
package/engine/server.ts CHANGED
@@ -472,7 +472,6 @@ export class ChannelEngine {
472
472
  async updateChannelsAsync(channelMgr, options) {
473
473
  debug(`Do we have any new channels?`);
474
474
  const newChannels = channelMgr.getChannels().filter(channel => !sessions[channel.id]);
475
- debug(JSON.stringify(newChannels));
476
475
  const addAsync = async (channel) => {
477
476
  debug(`Adding channel with ID ${channel.id}`);
478
477
  sessions[channel.id] = new Session(this.assetMgr, {
package/engine/session.js CHANGED
@@ -9,7 +9,14 @@ 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, codecsFromString, roundToThreeDecimals } = require('./util.js');
12
+ const {
13
+ applyFilter,
14
+ cloudWatchLog,
15
+ m3u8Header,
16
+ logerror,
17
+ codecsFromString,
18
+ roundToThreeDecimals
19
+ } = require('./util.js');
13
20
  const ChaosMonkey = require('./chaos_monkey.js');
14
21
 
15
22
  const EVENT_LIST_LIMIT = 100;
@@ -281,7 +288,7 @@ class Session {
281
288
  numberOfLargeTicks++;
282
289
  }
283
290
  } else {
284
- console.warn(`[${this._sessionId}]: Playhead tick interval went over Max tick interval by ${changeMaxTick}ms.
291
+ debug(`[${this._sessionId}]: Playhead tick interval went over Max tick interval by ${changeMaxTick}ms.
285
292
  If the value keeps increasing, consider increasing the 'maxTickInterval' in engineOptions`);
286
293
  }
287
294
  tickInterval = this.maxTickInterval / 1000;
@@ -1301,11 +1308,8 @@ class Session {
1301
1308
  await loadPromise;
1302
1309
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session',
1303
1310
  { event: 'loadVod', channel: this._sessionId, loadTimeMs: Date.now() - loadStart });
1304
- debug(`[${this._sessionId}]: first VOD loaded`);
1305
- debug(`[${this._sessionId}]: ${currentVod.getDeltaTimes()}`);
1306
- debug(`[${this._sessionId}]: playhead positions [V]=${currentVod.getPlayheadPositions("video")}`);
1307
- debug(`[${this._sessionId}]: playhead positions [A]=${currentVod.getPlayheadPositions("audio")}`);
1308
- debug(`[${this._sessionId}]: playhead positions [S]=${currentVod.getPlayheadPositions("subtitle")}`);
1311
+ debug(`[${this._sessionId}]: first VOD loaded. DeltaTimes ${currentVod.getDeltaTimes().map(roundToThreeDecimals).join(",")}`);
1312
+ this._logAllPlayheadPositions(this._sessionId, currentVod);
1309
1313
  //debug(newVod);
1310
1314
  const updatedSessionState = await this._sessionState.setValues({
1311
1315
  "mediaSeq": 0,
@@ -1505,10 +1509,8 @@ class Session {
1505
1509
  cloudWatchLog(!this.cloudWatchLogging, 'engine-session',
1506
1510
  { event: 'loadVod', channel: this._sessionId, loadTimeMs: Date.now() - loadStart });
1507
1511
  this.leaderIsSettingNextVod = true;
1508
- debug(`[${this._sessionId}]: next VOD loaded (${newVod.getDeltaTimes()})`);
1509
- debug(`[${this._sessionId}]: playhead positions [V]=${newVod.getPlayheadPositions("video")}`);
1510
- debug(`[${this._sessionId}]: playhead positions [A]=${newVod.getPlayheadPositions("audio")}`);
1511
- debug(`[${this._sessionId}]: playhead positions [S]=${newVod.getPlayheadPositions("subtitle")}`);
1512
+ debug(`[${this._sessionId}]: next VOD loaded (${newVod.getDeltaTimes().map(roundToThreeDecimals).join(",")})`);
1513
+ this._logAllPlayheadPositions(this._sessionId, newVod);
1512
1514
  currentVod = newVod;
1513
1515
  debug(`[${this._sessionId}]: msequences=${currentVod.getLiveMediaSequencesCount()}; audio msequences=${currentVod.getLiveMediaSequencesCount("audio")}; subtitle msequences=${currentVod.getLiveMediaSequencesCount("subtitle")}`);
1514
1516
  sessionState.currentVod = await this._sessionState.setCurrentVod(currentVod, { ttl: currentVod.getDuration() * 1000 });
@@ -2372,6 +2374,24 @@ class Session {
2372
2374
  logerror(this._sessionId, err);
2373
2375
  }
2374
2376
  }
2377
+
2378
+ _logAllPlayheadPositions = (sessionId, vod) => {
2379
+ if (!vod) {
2380
+ return;
2381
+ }
2382
+ if (!vod.getPlayheadPositions) {
2383
+ return;
2384
+ }
2385
+ if (vod.getPlayheadPositions("video")) {
2386
+ debug(`[${sessionId}]: playhead positions [V]=${vod.getPlayheadPositions("video").map(roundToThreeDecimals).join(",")}`);
2387
+ }
2388
+ if (vod.getPlayheadPositions("audio")) {
2389
+ debug(`[${sessionId}]: playhead positions [A]=${vod.getPlayheadPositions("audio").map(roundToThreeDecimals).join(",")}`);
2390
+ }
2391
+ if (vod.getPlayheadPositions("subtitle")) {
2392
+ debug(`[${sessionId}]: playhead positions [S]=${vod.getPlayheadPositions("subtitle").map(roundToThreeDecimals).join(",")}`);
2393
+ }
2394
+ };
2375
2395
  }
2376
2396
 
2377
2397
  module.exports = Session;
package/engine/util.js CHANGED
@@ -257,6 +257,14 @@ const timeLeft = (endTimestamp, currentTimestamp) => {
257
257
  };
258
258
 
259
259
  const roundToThreeDecimals = (number) => {
260
+ if (typeof number !== "number") {
261
+ try {
262
+ number = parseFloat(number);
263
+ } catch (e) {
264
+ console.error("Could not convert to number:", number);
265
+ return number;
266
+ }
267
+ }
260
268
  const r = Math.round(number * 1000) / 1000;
261
269
  return r
262
270
  }
@@ -12,9 +12,9 @@ import { ChannelEngine, ChannelEngineOpts,
12
12
  const DEMUX_CONTENT = {
13
13
  TS: {
14
14
  slate: "https://testcontent.eyevinn.technology/ce_test_content/DEMUX_VINJETTE_TS_001/master.m3u8",
15
- vod: "https://testcontent.eyevinn.technology/ce_test_content/DEMUX_VOD_TS_001/master.m3u8", // Elephant's Dream 11 min
16
- trailer: "https://testcontent.eyevinn.technology/ce_test_content/DEMUX_TRAILER_TS_001/index.m3u8",
17
- bumper: "https://testcontent.eyevinn.technology/ce_test_content/DEMUX_VINJETTE_TS_001/master.m3u8",
15
+ vod: "https://maitv-vod.lab.eyevinn.technology/VINN.mp4/master_demux.m3u8",
16
+ trailer: "https://maitv-vod.lab.eyevinn.technology/ads/apotea-15s.mp4/master_demux.m3u8",
17
+ bumper: "https://testcontent.eyevinn.technology/ce_test_content/DEMUX_VINJETTE_TS_001/master.m3u8",
18
18
  // If you do not have a demux live stream available, you can always use a local CE V2L stream (ex: demux.ts)
19
19
  live: null
20
20
  },
@@ -28,7 +28,7 @@ import { ChannelEngine, ChannelEngineOpts,
28
28
  }
29
29
  };
30
30
 
31
- const HLS_CONTENT = DEMUX_CONTENT.CMAF;
31
+ const HLS_CONTENT = DEMUX_CONTENT.TS;
32
32
 
33
33
  let FIRST_PLAYED_VOD = true;
34
34
 
@@ -98,13 +98,13 @@ import { ChannelEngine, ChannelEngineOpts,
98
98
  };
99
99
  resolve(vodResponse);
100
100
  } else {
101
- FIRST_PLAYED_VOD = false;
102
101
  const vodResponse = {
103
102
  id: vod.id,
104
103
  title: vod.title,
105
104
  uri: vod.uri,
106
105
  unixTs: unixTs
107
106
  };
107
+ FIRST_PLAYED_VOD = false;
108
108
  resolve(vodResponse);
109
109
  }
110
110
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "5.0.0",
3
+ "version": "5.0.3",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,8 +30,8 @@
30
30
  "license": "Apache-2.0",
31
31
  "dependencies": {
32
32
  "@eyevinn/hls-repeat": "^0.2.1",
33
- "@eyevinn/hls-truncate": "^0.3.1",
34
- "@eyevinn/hls-vodtolive": "^4.1.5",
33
+ "@eyevinn/hls-truncate": "^0.3.3",
34
+ "@eyevinn/hls-vodtolive": "^4.1.7",
35
35
  "@eyevinn/m3u8": "^0.5.6",
36
36
  "@fastify/static": "^5.0.0",
37
37
  "abort-controller": "^3.0.0",