eyevinn-channel-engine 4.3.1 → 4.3.3-rc.0

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/Dockerfile CHANGED
@@ -1,10 +1,11 @@
1
- FROM node:12.16.1-alpine
1
+ FROM node:18-alpine
2
2
 
3
3
  WORKDIR /app
4
4
 
5
5
  ADD . .
6
6
 
7
7
  RUN npm install
8
+ RUN npm run build
8
9
  ENV DEBUG=engine*
9
10
 
10
- CMD ["npm", "start"]
11
+ CMD ["npm", "start"]
@@ -5,6 +5,7 @@ declare class MemcachedStateStore {
5
5
  client: any;
6
6
  initAsync(id: any, initData: any): Promise<{}>;
7
7
  resetAsync(id: any, initData: any): Promise<void>;
8
+ resetAllAsync(): Promise<void>;
8
9
  getAsync(id: any, key: any): Promise<any>;
9
10
  setAsync(id: any, key: any, value: any): Promise<any>;
10
11
  setVolatileAsync(id: any, key: any, value: any): Promise<void>;
@@ -112,6 +112,14 @@ var MemcachedStateStore = /** @class */ (function () {
112
112
  });
113
113
  });
114
114
  };
115
+ MemcachedStateStore.prototype.resetAllAsync = function () {
116
+ return __awaiter(this, void 0, void 0, function () {
117
+ return __generator(this, function (_a) {
118
+ console.error("Shared Storage Reset Failed.\nMemcache-client: Flush All Command Not Implemented Yet");
119
+ return [2 /*return*/];
120
+ });
121
+ });
122
+ };
115
123
  MemcachedStateStore.prototype.getAsync = function (id, key) {
116
124
  return __awaiter(this, void 0, void 0, function () {
117
125
  var storeKey, data;
@@ -4,6 +4,8 @@ declare class MemoryStateStore {
4
4
  sharedStates: {};
5
5
  globalSharedStates: {};
6
6
  initAsync(id: any, initData: any): Promise<any>;
7
+ resetAsync(id: any, initData: any): Promise<void>;
8
+ resetAllAsync(): Promise<void>;
7
9
  getAsync(id: any, key: any): Promise<any>;
8
10
  setAsync(id: any, key: any, value: any): Promise<any>;
9
11
  setVolatileAsync(id: any, key: any, value: any): Promise<any>;
@@ -54,6 +54,29 @@ var MemoryStateStore = /** @class */ (function () {
54
54
  });
55
55
  });
56
56
  };
57
+ MemoryStateStore.prototype.resetAsync = function (id, initData) {
58
+ return __awaiter(this, void 0, void 0, function () {
59
+ return __generator(this, function (_a) {
60
+ switch (_a.label) {
61
+ case 0:
62
+ this.sharedStates[id] = null;
63
+ return [4 /*yield*/, this.initAsync(id, initData)];
64
+ case 1:
65
+ _a.sent();
66
+ return [2 /*return*/];
67
+ }
68
+ });
69
+ });
70
+ };
71
+ MemoryStateStore.prototype.resetAllAsync = function () {
72
+ return __awaiter(this, void 0, void 0, function () {
73
+ return __generator(this, function (_a) {
74
+ this.sharedStates = {};
75
+ this.globalSharedStates = {};
76
+ return [2 /*return*/];
77
+ });
78
+ });
79
+ };
57
80
  MemoryStateStore.prototype.getAsync = function (id, key) {
58
81
  return __awaiter(this, void 0, void 0, function () {
59
82
  var value;
@@ -62,6 +85,9 @@ var MemoryStateStore = /** @class */ (function () {
62
85
  value = this.globalSharedStates[key];
63
86
  }
64
87
  else {
88
+ if (!this.sharedStates[id]) {
89
+ return [2 /*return*/, null];
90
+ }
65
91
  value = this.sharedStates[id][key];
66
92
  }
67
93
  return [2 /*return*/, value];
@@ -75,6 +101,9 @@ var MemoryStateStore = /** @class */ (function () {
75
101
  this.globalSharedStates[key] = value;
76
102
  }
77
103
  else {
104
+ if (!this.sharedStates[id]) {
105
+ this.sharedStates[id] = {};
106
+ }
78
107
  this.sharedStates[id][key] = value;
79
108
  return [2 /*return*/, this.sharedStates[id][key]];
80
109
  }
@@ -6,6 +6,7 @@ declare class RedisStateStore {
6
6
  client: any;
7
7
  initAsync(id: any, initData: any): Promise<{}>;
8
8
  resetAsync(id: any, initData: any): Promise<void>;
9
+ resetAllAsync(): Promise<void>;
9
10
  getAsync(id: any, key: any): Promise<any>;
10
11
  setAsync(id: any, key: any, value: any): Promise<any>;
11
12
  setVolatileAsync(id: any, key: any, value: any): Promise<any>;
@@ -34,7 +34,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
34
34
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
35
  }
36
36
  };
37
- var createClient = require("redis").createClient;
37
+ var Redis = require("ioredis");
38
38
  var debug = require("debug")("redis-state-store");
39
39
  var DEFAULT_VOLATILE_KEY_TTL = 5; // Timeout so it should not expire within one normal increment iteration (in seconds)
40
40
  var RedisStateStore = /** @class */ (function () {
@@ -50,7 +50,7 @@ var RedisStateStore = /** @class */ (function () {
50
50
  debug("Overriding default, volatileKeyTTL=".concat(opts.volatileKeyTTL, "s"));
51
51
  this.volatileKeyTTL = opts.volatileKeyTTL;
52
52
  }
53
- this.client = createClient(opts.redisUrl);
53
+ this.client = new Redis(opts.redisUrl);
54
54
  }
55
55
  RedisStateStore.prototype.initAsync = function (id, initData) {
56
56
  return __awaiter(this, void 0, void 0, function () {
@@ -104,6 +104,21 @@ var RedisStateStore = /** @class */ (function () {
104
104
  });
105
105
  };
106
106
  RedisStateStore.prototype.resetAsync = function (id, initData) {
107
+ return __awaiter(this, void 0, void 0, function () {
108
+ return __generator(this, function (_a) {
109
+ switch (_a.label) {
110
+ case 0: return [4 /*yield*/, this.setAsync(id, "_initiated", false)];
111
+ case 1:
112
+ _a.sent();
113
+ return [4 /*yield*/, this.initAsync(id, initData)];
114
+ case 2:
115
+ _a.sent();
116
+ return [2 /*return*/];
117
+ }
118
+ });
119
+ });
120
+ };
121
+ RedisStateStore.prototype.resetAllAsync = function () {
107
122
  return __awaiter(this, void 0, void 0, function () {
108
123
  var resetAsync;
109
124
  var _this = this;
@@ -170,7 +185,7 @@ var RedisStateStore = /** @class */ (function () {
170
185
  setAsync = new Promise(function (resolve, reject) {
171
186
  _this.client.set(storeKey, JSON.stringify(value), function (err, res) {
172
187
  var ioTimeMs = Date.now() - startMs;
173
- debug("REDIS set ".concat(storeKey, ": ").concat(res, " (").concat(ioTimeMs, "ms) ").concat(ioTimeMs > 1000 ? 'REDISSLOW!' : ''));
188
+ debug("REDIS set ".concat(storeKey, ": ").concat(res, " (").concat(ioTimeMs, "ms) ").concat(ioTimeMs > 1000 ? "REDISSLOW!" : ""));
174
189
  if (!err) {
175
190
  resolve(value);
176
191
  }
@@ -226,7 +241,7 @@ var RedisStateStore = /** @class */ (function () {
226
241
  delAsync = new Promise(function (resolve, reject) {
227
242
  _this.client.del(storeKey, function (err, res) {
228
243
  var ioTimeMs = Date.now() - startMs;
229
- debug("REDIS remove ".concat(storeKey, ": (").concat(ioTimeMs, "ms) ").concat(ioTimeMs > 1000 ? 'REDISSLOW!' : ''));
244
+ debug("REDIS remove ".concat(storeKey, ": (").concat(ioTimeMs, "ms) ").concat(ioTimeMs > 1000 ? "REDISSLOW!" : ""));
230
245
  if (!err) {
231
246
  resolve();
232
247
  }
@@ -29,6 +29,7 @@ export interface ChannelEngineOpts {
29
29
  noSessionDataTags?: boolean;
30
30
  volatileKeyTTL?: number;
31
31
  autoCreateSession?: boolean;
32
+ sessionResetKey?: string;
32
33
  }
33
34
  export interface VodRequest {
34
35
  sessionId: string;
@@ -147,6 +148,7 @@ export declare class ChannelEngine {
147
148
  private adCopyMgrUri?;
148
149
  private adXchangeUri?;
149
150
  private autoCreateSession;
151
+ private sessionResetKey;
150
152
  constructor(assetMgr: IAssetManager, options?: ChannelEngineOpts);
151
153
  updateStreamSwitchAsync(): Promise<void>;
152
154
  updateChannelsAsync(channelMgr: any, options: any): Promise<void>;
@@ -172,6 +174,7 @@ export declare class ChannelEngine {
172
174
  _handleStatus(req: any, res: any, next: any): Promise<void>;
173
175
  _handleAggregatedSessionHealth(req: any, res: any, next: any): Promise<void>;
174
176
  _handleSessionHealth(req: any, res: any, next: any): Promise<void>;
177
+ _handleSessionsReset(req: any, res: any, next: any): Promise<void>;
175
178
  _handleSessionReset(req: any, res: any, next: any): Promise<void>;
176
179
  _gracefulErrorHandler(errMsg: any): any;
177
180
  _errorHandler(errMsg: any): any;
@@ -71,6 +71,7 @@ var ChannelEngine = /** @class */ (function () {
71
71
  function ChannelEngine(assetMgr, options) {
72
72
  var _this = this;
73
73
  this.autoCreateSession = false;
74
+ this.sessionResetKey = "";
74
75
  this.options = options;
75
76
  if (options && options.adCopyMgrUri) {
76
77
  this.adCopyMgrUri = options.adCopyMgrUri;
@@ -85,6 +86,10 @@ var ChannelEngine = /** @class */ (function () {
85
86
  this.useVTTSubtitles = (options && options.useVTTSubtitles) ? options.useVTTSubtitles : false;
86
87
  this.dummySubtitleEndpoint = (options && options.dummySubtitleEndpoint) ? options.dummySubtitleEndpoint : DefaultDummySubtitleEndpointPath;
87
88
  this.subtitleSliceEndpoint = (options && options.subtitleSliceEndpoint) ? options.subtitleSliceEndpoint : DefaultSubtitleSpliceEndpointPath;
89
+ this.sessionResetKey = "";
90
+ if (options && options.sessionResetKey) {
91
+ this.sessionResetKey = options.sessionResetKey;
92
+ }
88
93
  this.alwaysNewSegments = false;
89
94
  if (options && options.alwaysNewSegments) {
90
95
  this.alwaysNewSegments = true;
@@ -262,7 +267,8 @@ var ChannelEngine = /** @class */ (function () {
262
267
  this.server.get('/status/:sessionId', this._handleStatus.bind(this));
263
268
  this.server.get('/health', this._handleAggregatedSessionHealth.bind(this));
264
269
  this.server.get('/health/:sessionId', this._handleSessionHealth.bind(this));
265
- this.server.get('/reset', this._handleSessionReset.bind(this));
270
+ this.server.get('/reset', this._handleSessionsReset.bind(this));
271
+ this.server.get('/reset/:sessionId', this._handleSessionReset.bind(this));
266
272
  this.server.get(DefaultDummySubtitleEndpointPath, this._handleDummySubtitleEndpoint.bind(this));
267
273
  this.server.get(DefaultSubtitleSpliceEndpointPath, this._handleSubtitleSliceEndpoint.bind(this));
268
274
  this.server.on('NotFound', function (req, res, err, next) {
@@ -445,6 +451,7 @@ var ChannelEngine = /** @class */ (function () {
445
451
  subtitleSliceEndpoint: this.subtitleSliceEndpoint,
446
452
  useVTTSubtitles: this.useVTTSubtitles,
447
453
  alwaysNewSegments: options.alwaysNewSegments,
454
+ sessionResetKey: options.sessionResetKey,
448
455
  partialStoreHLSVod: options.partialStoreHLSVod,
449
456
  alwaysMapBandwidthByNearest: options.alwaysMapBandwidthByNearest,
450
457
  noSessionDataTags: options.noSessionDataTags,
@@ -1013,7 +1020,7 @@ var ChannelEngine = /** @class */ (function () {
1013
1020
  return __generator(this, function (_a) {
1014
1021
  debug("req.url=".concat(req.url));
1015
1022
  try {
1016
- body = "WEBVTT\nX-TIMESTAMP-MAP=MPEGTS:0,LOCAL:00:00:00.000";
1023
+ body = "WEBVTT\nX-TIMESTAMP-MAP=MPEGTS:0,LOCAL:00:00:00.000\n\n";
1017
1024
  res.sendRaw(200, Buffer.from(body, 'utf8'), {
1018
1025
  "Content-Type": "text/vtt",
1019
1026
  "Access-Control-Allow-Origin": "*",
@@ -1275,13 +1282,22 @@ var ChannelEngine = /** @class */ (function () {
1275
1282
  });
1276
1283
  });
1277
1284
  };
1278
- ChannelEngine.prototype._handleSessionReset = function (req, res, next) {
1285
+ ChannelEngine.prototype._handleSessionsReset = function (req, res, next) {
1279
1286
  return __awaiter(this, void 0, void 0, function () {
1280
1287
  var sessionResets, _i, _a, sessionId, session, sessionLive, err;
1281
1288
  return __generator(this, function (_b) {
1282
1289
  switch (_b.label) {
1283
1290
  case 0:
1284
1291
  debug("req.url=".concat(req.url));
1292
+ if (this.sessionResetKey && req.query.key !== this.sessionResetKey) {
1293
+ res.sendRaw(403, JSON.stringify({ "message": "Invalid Session-Reset-Key" }), {
1294
+ "Content-Type": "application/json",
1295
+ "Access-Control-Allow-Origin": "*",
1296
+ "Cache-Control": "no-cache",
1297
+ });
1298
+ next();
1299
+ return [2 /*return*/];
1300
+ }
1285
1301
  sessionResets = [];
1286
1302
  _i = 0, _a = Object.keys(sessions);
1287
1303
  _b.label = 1;
@@ -1314,6 +1330,69 @@ var ChannelEngine = /** @class */ (function () {
1314
1330
  });
1315
1331
  });
1316
1332
  };
1333
+ ChannelEngine.prototype._handleSessionReset = function (req, res, next) {
1334
+ return __awaiter(this, void 0, void 0, function () {
1335
+ var sessionId, sessionResets, session, sessionLive, e_1, err;
1336
+ return __generator(this, function (_a) {
1337
+ switch (_a.label) {
1338
+ case 0:
1339
+ debug("req.url=".concat(req.url));
1340
+ if (this.sessionResetKey && req.query.key !== this.sessionResetKey) {
1341
+ res.sendRaw(403, JSON.stringify({ "message": "Invalid Session-Reset-Key" }), {
1342
+ "Content-Type": "application/json",
1343
+ "Access-Control-Allow-Origin": "*",
1344
+ "Cache-Control": "no-cache",
1345
+ });
1346
+ next();
1347
+ return [2 /*return*/];
1348
+ }
1349
+ _a.label = 1;
1350
+ case 1:
1351
+ _a.trys.push([1, 5, , 6]);
1352
+ sessionId = void 0;
1353
+ if (req.params && req.params.sessionId) {
1354
+ sessionId = req.params.sessionId;
1355
+ }
1356
+ sessionResets = [];
1357
+ session = sessions[sessionId];
1358
+ sessionLive = sessionsLive[sessionId];
1359
+ if (!(session && sessionLive)) return [3 /*break*/, 3];
1360
+ return [4 /*yield*/, session.resetAsync(sessionId)];
1361
+ case 2:
1362
+ _a.sent();
1363
+ sessionResets.push(sessionId);
1364
+ return [3 /*break*/, 4];
1365
+ case 3:
1366
+ res.sendRaw(400, JSON.stringify({ "message": "Invalid Session ID" }), {
1367
+ "Content-Type": "application/json",
1368
+ "Access-Control-Allow-Origin": "*",
1369
+ "Cache-Control": "no-cache",
1370
+ });
1371
+ next();
1372
+ return [2 /*return*/];
1373
+ case 4:
1374
+ res.sendRaw(200, JSON.stringify({ "status": "ok", "instanceId": this.instanceId, "resets": sessionResets }), {
1375
+ "Content-Type": "application/json",
1376
+ "Access-Control-Allow-Origin": "*",
1377
+ "Cache-Control": "no-cache",
1378
+ });
1379
+ next();
1380
+ return [3 /*break*/, 6];
1381
+ case 5:
1382
+ e_1 = _a.sent();
1383
+ res.sendRaw(500, JSON.stringify({ "error": e_1 }), {
1384
+ "Content-Type": "application/json",
1385
+ "Access-Control-Allow-Origin": "*",
1386
+ "Cache-Control": "no-cache",
1387
+ });
1388
+ err = new errs.NotFoundError('Session Reset Failed');
1389
+ next(err);
1390
+ return [3 /*break*/, 6];
1391
+ case 6: return [2 /*return*/];
1392
+ }
1393
+ });
1394
+ });
1395
+ };
1317
1396
  ChannelEngine.prototype._gracefulErrorHandler = function (errMsg) {
1318
1397
  console.error(errMsg);
1319
1398
  var err = new errs.NotFoundError(errMsg);
@@ -83,7 +83,7 @@ declare class Session {
83
83
  } | {
84
84
  sessionId: any;
85
85
  }>;
86
- resetAsync(): Promise<void>;
86
+ resetAsync(id: any): Promise<void>;
87
87
  getSessionState(): Promise<any>;
88
88
  getTruncatedVodSegments(vodUri: any, duration: any): Promise<any>;
89
89
  setCurrentMediaSequenceSegments(segments: any, mSeqOffset: any, reloadBehind: any): Promise<void>;
@@ -454,15 +454,24 @@ var Session = /** @class */ (function () {
454
454
  });
455
455
  });
456
456
  };
457
- Session.prototype.resetAsync = function () {
457
+ Session.prototype.resetAsync = function (id) {
458
458
  return __awaiter(this, void 0, void 0, function () {
459
459
  return __generator(this, function (_a) {
460
460
  switch (_a.label) {
461
- case 0: return [4 /*yield*/, this._sessionStateStore.reset(this._sessionId)];
461
+ case 0:
462
+ if (!id) return [3 /*break*/, 3];
463
+ return [4 /*yield*/, this._sessionStateStore.reset(id)];
462
464
  case 1:
463
465
  _a.sent();
464
- return [4 /*yield*/, this._playheadStateStore.reset(this._sessionId)];
466
+ return [4 /*yield*/, this._playheadStateStore.reset(id)];
465
467
  case 2:
468
+ _a.sent();
469
+ _a.label = 3;
470
+ case 3: return [4 /*yield*/, this._sessionStateStore.resetAll()];
471
+ case 4:
472
+ _a.sent();
473
+ return [4 /*yield*/, this._playheadStateStore.resetAll()];
474
+ case 5:
466
475
  _a.sent();
467
476
  return [2 /*return*/];
468
477
  }
@@ -10,6 +10,7 @@ declare class SharedStateStore {
10
10
  isShared(): boolean;
11
11
  init(id: any): Promise<void>;
12
12
  reset(id: any): Promise<void>;
13
+ resetAll(): Promise<void>;
13
14
  get(id: any, key: any): Promise<any>;
14
15
  set(id: any, key: any, value: any): Promise<any>;
15
16
  setVolatile(id: any, key: any, value: any): Promise<any>;
@@ -87,6 +87,18 @@ var SharedStateStore = /** @class */ (function () {
87
87
  });
88
88
  });
89
89
  };
90
+ SharedStateStore.prototype.resetAll = function () {
91
+ return __awaiter(this, void 0, void 0, function () {
92
+ return __generator(this, function (_a) {
93
+ switch (_a.label) {
94
+ case 0: return [4 /*yield*/, this.store.resetAllAsync()];
95
+ case 1:
96
+ _a.sent();
97
+ return [2 /*return*/];
98
+ }
99
+ });
100
+ });
101
+ };
90
102
  SharedStateStore.prototype.get = function (id, key) {
91
103
  return __awaiter(this, void 0, void 0, function () {
92
104
  var data;
@@ -4,26 +4,29 @@
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  var index_1 = require("../index");
7
- var STITCH_ENDPOINT = process.env.STITCH_ENDPOINT ||
8
- "http://lambda.eyevinn.technology/stitch/master.m3u8";
9
7
  var RefAssetManager = /** @class */ (function () {
10
8
  function RefAssetManager(opts) {
11
9
  this.assets = {
12
10
  1: [
13
11
  {
14
12
  id: 1,
13
+ title: "Streaming Tech TV+",
14
+ uri: "https://lab.cdn.eyevinn.technology/stswetvplus-promo-2023-5GBm231Mkz.mov/manifest.m3u8",
15
+ },
16
+ {
17
+ id: 2,
15
18
  title: "Tears of Steel",
16
19
  uri: "https://maitv-vod.lab.eyevinn.technology/tearsofsteel_4k.mov/master.m3u8",
17
20
  },
18
21
  {
19
- id: 2,
22
+ id: 3,
20
23
  title: "VINN",
21
24
  uri: "https://maitv-vod.lab.eyevinn.technology/VINN.mp4/master.m3u8",
22
25
  },
23
26
  ],
24
27
  };
25
28
  this.pos = {
26
- 1: 1,
29
+ 1: 0,
27
30
  };
28
31
  }
29
32
  /**
@@ -44,22 +47,10 @@ var RefAssetManager = /** @class */ (function () {
44
47
  if (_this.pos[channelId] > _this.assets[channelId].length - 1) {
45
48
  _this.pos[channelId] = 0;
46
49
  }
47
- var payload = {
48
- uri: vod.uri,
49
- breaks: [
50
- {
51
- pos: 100,
52
- duration: 15 * 1000,
53
- url: "https://maitv-vod.lab.eyevinn.technology/ads/6cd7d768_e214_4ebc_9f14_7ed89710115e_mp4/master.m3u8",
54
- },
55
- ],
56
- };
57
- var buff = Buffer.from(JSON.stringify(payload));
58
- var encodedPayload = buff.toString("base64");
59
50
  var vodResponse = {
60
51
  id: vod.id,
61
52
  title: vod.title,
62
- uri: STITCH_ENDPOINT + "?payload=" + encodedPayload,
53
+ uri: vod.uri,
63
54
  };
64
55
  resolve(vodResponse);
65
56
  }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyevinn-channel-engine",
3
- "version": "4.3.1",
3
+ "version": "4.3.3-rc.0",
4
4
  "description": "OTT TV Channel Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,6 +34,7 @@
34
34
  "@eyevinn/m3u8": "^0.5.3",
35
35
  "abort-controller": "^3.0.0",
36
36
  "debug": "^3.2.7",
37
+ "ioredis": "^5.3.2",
37
38
  "memcache-client": "^0.10.1",
38
39
  "nock": "^13.1.1",
39
40
  "node-fetch": "^2.6.1",
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ /*
3
+ * Reference implementation of Channel Engine library using demuxed VOD assets.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var index_1 = require("./index");
7
+ var RefAssetManager = /** @class */ (function () {
8
+ function RefAssetManager(opts) {
9
+ this.assets = {
10
+ 1: [
11
+ {
12
+ id: 1,
13
+ title: "Elephants dream",
14
+ uri: "https://playertest.longtailvideo.com/adaptive/elephants_dream_v4/index.m3u8",
15
+ },
16
+ {
17
+ id: 2,
18
+ title: "Test HLS Bird noises (1m10s)",
19
+ uri: "https://mtoczko.github.io/hls-test-streams/test-audio-pdt/playlist.m3u8",
20
+ },
21
+ ],
22
+ };
23
+ this.pos = {
24
+ 1: 0,
25
+ };
26
+ }
27
+ /**
28
+ *
29
+ * @param {Object} vodRequest
30
+ * {
31
+ * sessionId,
32
+ * category,
33
+ * playlistId
34
+ * }
35
+ */
36
+ RefAssetManager.prototype.getNextVod = function (vodRequest) {
37
+ var _this = this;
38
+ return new Promise(function (resolve, reject) {
39
+ var channelId = vodRequest.playlistId;
40
+ if (_this.assets[channelId]) {
41
+ var vod = _this.assets[channelId][_this.pos[channelId]++];
42
+ if (_this.pos[channelId] > _this.assets[channelId].length - 1) {
43
+ _this.pos[channelId] = 0;
44
+ }
45
+ resolve(vod);
46
+ }
47
+ else {
48
+ reject("Invalid channelId provided");
49
+ }
50
+ });
51
+ };
52
+ return RefAssetManager;
53
+ }());
54
+ var RefChannelManager = /** @class */ (function () {
55
+ function RefChannelManager() {
56
+ }
57
+ RefChannelManager.prototype.getChannels = function () {
58
+ return [{ id: "1", profile: this._getProfile(), audioTracks: this._getAudioTracks(), subtitleTracks: this._getSubtitleTracks() }];
59
+ };
60
+ RefChannelManager.prototype._getProfile = function () {
61
+ return [
62
+ {
63
+ bw: 7934000,
64
+ codecs: "avc1.4d001f,mp4a.40.2",
65
+ resolution: [2880, 1440],
66
+ },
67
+ {
68
+ bw: 7514000,
69
+ codecs: "avc1.4d001f,mp4a.40.2",
70
+ resolution: [1920, 1080],
71
+ },
72
+ { bw: 7134000, codecs: "avc1.4d001f,mp4a.40.2", resolution: [1280, 720] },
73
+ { bw: 6134000, codecs: "avc1.4d001f,mp4a.40.2", resolution: [1024, 458] },
74
+ { bw: 2323000, codecs: "avc1.4d001f,mp4a.40.2", resolution: [640, 286] },
75
+ { bw: 495894, codecs: "avc1.4d001f,mp4a.40.2", resolution: [480, 214] },
76
+ ];
77
+ };
78
+ RefChannelManager.prototype._getAudioTracks = function () {
79
+ return [
80
+ { language: "en", name: "English", default: true },
81
+ { language: "es", name: "Spanish", default: false },
82
+ ];
83
+ };
84
+ RefChannelManager.prototype._getSubtitleTracks = function () {
85
+ return [
86
+ { language: "zh", name: "chinese", default: true },
87
+ { language: "fr", name: "french", default: false }
88
+ ];
89
+ };
90
+ return RefChannelManager;
91
+ }());
92
+ var refAssetManager = new RefAssetManager();
93
+ var refChannelManager = new RefChannelManager();
94
+ var engineOptions = {
95
+ heartbeat: "/",
96
+ averageSegmentDuration: 2000,
97
+ channelManager: refChannelManager,
98
+ defaultSlateUri: "https://mtoczko.github.io/hls-test-streams/test-audio-pdt/playlist.m3u8",
99
+ slateRepetitions: 10,
100
+ redisUrl: process.env.REDIS_URL,
101
+ useDemuxedAudio: true,
102
+ alwaysNewSegments: false,
103
+ useVTTSubtitles: true
104
+ };
105
+ var engine = new index_1.ChannelEngine(refAssetManager, engineOptions);
106
+ engine.start();
107
+ engine.listen(process.env.PORT || 8000);
@@ -0,0 +1 @@
1
+ export {};