eyevinn-channel-engine 5.0.0 → 5.0.2
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.
- package/dist/engine/session.d.ts +1 -0
- package/dist/engine/session.js +22 -10
- package/dist/engine/util.d.ts +1 -1
- package/dist/engine/util.js +9 -0
- package/dist/examples/livemix-demux.js +4 -4
- package/dist/package.json +3 -3
- package/engine/session.js +31 -11
- package/engine/util.js +8 -0
- package/examples/livemix-demux.ts +5 -5
- package/package.json +3 -3
package/dist/engine/session.d.ts
CHANGED
|
@@ -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
|
}
|
package/dist/engine/session.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
package/dist/engine/util.d.ts
CHANGED
|
@@ -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):
|
|
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;
|
package/dist/engine/util.js
CHANGED
|
@@ -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://
|
|
12
|
-
trailer: "https://
|
|
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.
|
|
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.
|
|
3
|
+
"version": "5.0.2",
|
|
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.
|
|
34
|
-
"@eyevinn/hls-vodtolive": "^4.1.
|
|
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/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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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://
|
|
16
|
-
trailer: "https://
|
|
17
|
-
bumper:
|
|
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.
|
|
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.
|
|
3
|
+
"version": "5.0.2",
|
|
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.
|
|
34
|
-
"@eyevinn/hls-vodtolive": "^4.1.
|
|
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",
|