eyevinn-channel-engine 5.1.2 → 5.2.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.
Files changed (97) hide show
  1. package/.github/workflows/nodejs.yml +1 -1
  2. package/.github/workflows/publish.yml +1 -1
  3. package/.github/workflows/rc.yml +1 -1
  4. package/CONTRIBUTING.md +40 -0
  5. package/Dockerfile +1 -1
  6. package/README.md +70 -8
  7. package/dist/engine/chaos_monkey.d.ts +1 -1
  8. package/dist/engine/chaos_monkey.js +1 -0
  9. package/dist/engine/event_stream.d.ts +1 -6
  10. package/dist/engine/event_stream.js +2 -0
  11. package/dist/engine/memcached_state_store.d.ts +1 -13
  12. package/dist/engine/memcached_state_store.js +4 -0
  13. package/dist/engine/memory_state_store.d.ts +1 -13
  14. package/dist/engine/memory_state_store.js +5 -0
  15. package/dist/engine/playhead_state.d.ts +0 -26
  16. package/dist/engine/playhead_state.js +9 -0
  17. package/dist/engine/preflight.d.ts +1 -1
  18. package/dist/engine/preflight.js +1 -0
  19. package/dist/engine/redis_state_store.d.ts +1 -19
  20. package/dist/engine/redis_state_store.js +5 -0
  21. package/dist/engine/server.d.ts +27 -0
  22. package/dist/engine/server.js +140 -6
  23. package/dist/engine/session.d.ts +1 -148
  24. package/dist/engine/session.js +398 -11
  25. package/dist/engine/session_live.d.ts +1 -181
  26. package/dist/engine/session_live.js +19 -4
  27. package/dist/engine/session_live_state.d.ts +0 -23
  28. package/dist/engine/session_live_state.js +5 -0
  29. package/dist/engine/session_state.d.ts +0 -45
  30. package/dist/engine/session_state.js +10 -0
  31. package/dist/engine/shared_state_store.d.ts +1 -25
  32. package/dist/engine/shared_state_store.js +10 -0
  33. package/dist/engine/state_store_types.d.ts +32 -0
  34. package/dist/engine/state_store_types.js +5 -0
  35. package/dist/engine/stream_switcher.d.ts +1 -40
  36. package/dist/engine/stream_switcher.js +108 -20
  37. package/dist/engine/subtitle_slicer.d.ts +1 -8
  38. package/dist/engine/subtitle_slicer.js +1 -0
  39. package/dist/engine/util.d.ts +1 -29
  40. package/dist/engine/util.js +2 -1
  41. package/dist/examples/adbreak.d.ts +1 -0
  42. package/dist/examples/adbreak.js +104 -0
  43. package/dist/index.d.ts +1 -1
  44. package/dist/package.json +20 -4
  45. package/docs/design/mixing-muxed-demuxed-audio.md +153 -0
  46. package/docs/design/subtitles-live-mix-demux.md +135 -0
  47. package/docs/reference.md +67 -0
  48. package/engine/chaos_monkey.ts +17 -0
  49. package/engine/{event_stream.js → event_stream.ts} +5 -3
  50. package/engine/{memcached_state_store.js → memcached_state_store.ts} +19 -12
  51. package/engine/memory_state_store.ts +71 -0
  52. package/engine/{playhead_state.js → playhead_state.ts} +92 -82
  53. package/engine/{preflight.js → preflight.ts} +1 -1
  54. package/engine/{redis_state_store.js → redis_state_store.ts} +216 -208
  55. package/engine/server.ts +210 -8
  56. package/engine/{session.js → session.ts} +421 -22
  57. package/engine/{session_live.js → session_live.ts} +54 -31
  58. package/engine/{session_live_state.js → session_live_state.ts} +129 -120
  59. package/engine/{session_state.js → session_state.ts} +269 -248
  60. package/engine/{shared_state_store.js → shared_state_store.ts} +31 -19
  61. package/engine/state_store_types.ts +35 -0
  62. package/engine/{stream_switcher.js → stream_switcher.ts} +133 -34
  63. package/engine/{subtitle_slicer.js → subtitle_slicer.ts} +10 -8
  64. package/engine/{util.js → util.ts} +28 -24
  65. package/examples/adbreak.ts +115 -0
  66. package/index.ts +2 -0
  67. package/package.json +20 -4
  68. package/spec/engine/custom_vod_request_params_spec.ts +99 -0
  69. package/spec/engine/drm_spec.ts +128 -0
  70. package/spec/engine/{engine_spec.js → engine_spec.ts} +44 -1
  71. package/spec/engine/{ha_spec.js → ha_spec.ts} +7 -4
  72. package/spec/engine/{init_switching_spec.js → init_switching_spec.ts} +10 -6
  73. package/spec/engine/{interface_spec.js → interface_spec.ts} +16 -4
  74. package/spec/engine/{playhead_live_spec.js → playhead_live_spec.ts} +2 -1
  75. package/spec/engine/{playhead_spec.js → playhead_spec.ts} +15 -8
  76. package/spec/engine/session_spec.ts +800 -0
  77. package/spec/engine/stream_switcher_audio_reconcile_spec.ts +158 -0
  78. package/spec/engine/{stream_switcher_spec.js → stream_switcher_spec.ts} +111 -13
  79. package/spec/engine/subtitle_missing_language_spec.ts +196 -0
  80. package/spec/engine/{subtitle_spec.js → subtitle_spec.ts} +28 -27
  81. package/spec/helpers/ts-resolve.js +65 -0
  82. package/spec/support/jasmine.json +1 -1
  83. package/spec/testvectors/hls_subs_no_language/config.subtitleTracks.json +12 -0
  84. package/spec/testvectors/hls_subs_no_language/evidence_dummy_segments_name_mismatch.m3u8 +24 -0
  85. package/spec/testvectors/hls_subs_no_language/evidence_real_cues_name_match.m3u8 +24 -0
  86. package/spec/testvectors/hls_subs_no_language/french.m3u8 +9 -0
  87. package/spec/testvectors/hls_subs_no_language/master.m3u8 +11 -0
  88. package/spec/testvectors/hls_subs_no_language/video.m3u8 +25 -0
  89. package/spec/testvectors/slate/master.m3u8 +3 -0
  90. package/spec/testvectors/slate/media.m3u8 +9 -0
  91. package/tsconfig.json +21 -4
  92. package/tsconfig.spec.json +16 -0
  93. package/engine/chaos_monkey.js +0 -17
  94. package/engine/memory_state_store.js +0 -63
  95. package/spec/engine/session_spec.js +0 -116
  96. /package/spec/engine/{session_live_spec.js → session_live_spec.ts} +0 -0
  97. /package/spec/engine/{util_spec.js → util_spec.ts} +0 -0
@@ -9,7 +9,7 @@ jobs:
9
9
 
10
10
  strategy:
11
11
  matrix:
12
- node-version: [20.x, 22.x]
12
+ node-version: [22.x, 24.x]
13
13
 
14
14
  steps:
15
15
  - uses: actions/checkout@v4
@@ -12,7 +12,7 @@ jobs:
12
12
  - uses: actions/checkout@v4
13
13
  - uses: actions/setup-node@v4
14
14
  with:
15
- node-version: 20
15
+ node-version: 24
16
16
  registry-url: https://registry.npmjs.org/
17
17
  - run: |
18
18
  npm ci
@@ -12,7 +12,7 @@ jobs:
12
12
  - uses: actions/checkout@v4
13
13
  - uses: actions/setup-node@v4
14
14
  with:
15
- node-version: 20
15
+ node-version: 24
16
16
  registry-url: https://registry.npmjs.org/
17
17
  - run: |
18
18
  npm ci
package/CONTRIBUTING.md CHANGED
@@ -17,6 +17,46 @@ We follow the [GitHub Flow](https://guides.github.com/introduction/flow/index.ht
17
17
 
18
18
  When submitting code changes your submissions are understood to be under the same MIT License that covers the project. Feel free to contact Eyevinn Technology if that's a concern.
19
19
 
20
+ # TypeScript migration
21
+
22
+ The `engine/` tree is being migrated from JavaScript to TypeScript **incrementally**, one
23
+ module at a time, so that `master` keeps building and testing green throughout. The build
24
+ (`npm run build`, which runs `tsc --project ./`) already compiles a mixed JS/TS tree because
25
+ `allowJs` is enabled in `tsconfig.json`.
26
+
27
+ ## Target strictness level
28
+
29
+ The end state is a fully-typed, strictly-checked tree:
30
+
31
+ - `strict: true` (implies `noImplicitAny`, `strictNullChecks`, etc.)
32
+ - `checkJs: true` for any remaining `.js` files
33
+
34
+ These global flags are **intentionally not enabled yet**. Turning them on across the ~7,500
35
+ LOC of currently-untyped JS would surface a large number of errors at once and break
36
+ `master`'s build. Instead, opt in **per file** as each module is hardened:
37
+
38
+ - Add `// @ts-check` at the top of a `.js` file to type-check just that file, or
39
+ - Convert the file to `.ts` (preferred — see checklist below).
40
+
41
+ The global `strict` / `checkJs` flags land **last**, in the final migration slice (**#376**),
42
+ once every module has already been converted or individually `@ts-check`-clean.
43
+
44
+ ## Per-file conversion checklist
45
+
46
+ Convert **one module per commit** to keep diffs reviewable and bisectable:
47
+
48
+ 1. Rename the file `.js` → `.ts` (use `git mv` to preserve history).
49
+ 2. Add explicit types for all exported functions, classes, and their public members.
50
+ 3. Keep the **public API and runtime behavior identical** — this is a type-only migration,
51
+ no behavior changes. Prefer `unknown` + narrowing over `any` where practical; leave a
52
+ `// TODO(ts):` note if a proper type is deferred.
53
+ 4. Run `npm run build && npm test` locally and confirm both are green (the jasmine suite must
54
+ report `0 failures`).
55
+ 5. Commit with a conventional-commit message, e.g. `refactor(engine): migrate util to TypeScript`.
56
+
57
+ CI already gates every push on `npm run build` (tsc) followed by `npm test`, so a file that
58
+ fails type-checking or breaks a test cannot land on `master`.
59
+
20
60
  # Code of Conduct
21
61
 
22
62
  ## Our Pledge
package/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM node:18-alpine
1
+ FROM node:24-alpine
2
2
 
3
3
  WORKDIR /app
4
4
 
package/README.md CHANGED
@@ -40,28 +40,89 @@ Please see the [Documentation](https://vod2live.docs.eyevinn.technology) for int
40
40
  - Develop adapters to plugin with custom scheduling endpoints
41
41
  - High Availability with Redis Cache or Valkey as shared state store
42
42
  - Support for WebVTT subtitles
43
- - Support for DRM encrypted HLS VODs (in beta)
43
+ - Support for Widevine DRM encrypted HLS+CMAF VODs (in beta); see `examples/drm.ts`
44
44
  - Improved performance with Redis connection pooling and pipelining
45
45
  - Enhanced stability in High Availability mode
46
46
  - Support for livemix with demuxed content (TS and CMAF)
47
+ - Support for SGAI HLS-interstitial ad breaks with client-side ad replacement
47
48
  - And much more!
48
49
 
50
+ ### Ad breaks (HLS interstitials)
51
+
52
+ A channel can be configured to open SGAI HLS-interstitial ad breaks. When
53
+ enabled, the engine emits EXT-X-DATERANGE interstitial metadata on the
54
+ manifest and resolves the ad asset from a configured ad-serving endpoint, with
55
+ a slate fallback if that endpoint cannot be reached. Configure it through the
56
+ `adBreak` option (engine-level default or per channel); see
57
+ [docs/reference.md](docs/reference.md#ad-break-configuration-hls-interstitials)
58
+ for the full field reference and `examples/adbreak.ts` for a runnable example.
59
+
60
+ ### Custom VOD request parameters
61
+
62
+ The engine can be configured with an allowlist of query-parameter names that
63
+ are permitted to be forwarded to the asset manager's `getNextVod()` request,
64
+ through the `customVodRequestParams` option on `ChannelEngineOpts`. Only
65
+ parameters named in the allowlist may be passed through; all others are
66
+ ignored, and the default (option omitted) is an empty allowlist with no
67
+ pass-through. See
68
+ [docs/reference.md](docs/reference.md#custom-vod-request-parameters) for the
69
+ field reference.
70
+
71
+ Declare the allowlist when creating the engine and read the forwarded values
72
+ from `vodRequest.customParams` in your asset manager's `getNextVod()`:
73
+
74
+ ```js
75
+ const { ChannelEngine } = require('eyevinn-channel-engine');
76
+
77
+ class MyAssetManager {
78
+ getNextVod(vodRequest) {
79
+ // Only allowlisted params are present; everything else is stripped.
80
+ // `customParams` is omitted entirely when no allowlisted param was sent.
81
+ const myparam = vodRequest.customParams && vodRequest.customParams.myparam;
82
+ return Promise.resolve({
83
+ id: '1',
84
+ title: 'Example',
85
+ uri: myparam
86
+ ? `https://vod.example.com/${myparam}/master.m3u8`
87
+ : 'https://vod.example.com/default/master.m3u8'
88
+ });
89
+ }
90
+ }
91
+
92
+ const engine = new ChannelEngine(new MyAssetManager(), {
93
+ channelManager: myChannelManager,
94
+ // Allowlist the query-parameter names to forward to getNextVod().
95
+ customVodRequestParams: ['myparam']
96
+ });
97
+ engine.start();
98
+ engine.listen(8000);
99
+ ```
100
+
101
+ A request such as:
102
+
103
+ ```
104
+ GET /channels/1/master.m3u8?myparam=foo
105
+ ```
106
+
107
+ forwards `{ myparam: 'foo' }` to `getNextVod()` via `vodRequest.customParams`.
108
+ Any query parameter not in `customVodRequestParams` (e.g. `?other=bar`) is
109
+ dropped before it reaches the asset manager.
110
+
49
111
  ## System Requirements
50
112
 
51
113
  Supported Node.js Versions
52
114
 
53
115
  | Version | Supported |
54
116
  | ------- | --------- |
55
- | 14.x | Yes |
56
- | 16.x | Yes |
57
- | 18.x | Yes |
117
+ | 22.x | Yes |
118
+ | 24.x | Yes |
58
119
 
59
120
  ## Supported Source Formats
60
121
 
61
- | HLS Format | Muxed | Demuxed | Mix w. Live | Subtitles | Mix w. Live & Subtitles | DRM |
62
- | ---------- | ----- | ------- | ----------- | --------- | ----------------------- | --- |
63
- | HLS + TS | Yes | Yes | Yes | Yes | No | No |
64
- | HLS + CMAF | Yes | Yes | Yes | Yes | No | No |
122
+ | HLS Format | Muxed | Demuxed | Mix w. Live | Subtitles | Mix w. Live & Subtitles | DRM |
123
+ | ---------- | ----- | ------- | ----------- | --------- | ----------------------- | -------------- |
124
+ | HLS + TS | Yes | Yes | Yes | Yes | No | No |
125
+ | HLS + CMAF | Yes | Yes | Yes | Yes | No | Yes (Widevine) |
65
126
 
66
127
  NOTE: The engine does not support subtitles in the live-mix + demux setting. Furthermore, then using the live-mix + demux setting, it is most optimal to use HLS content which has the same segment durations on all variants.
67
128
  Using a mix of different segment durations may result in occasional playback/audio sync issues, but not always. Further development will be needed to resolve this and improve the robustness of the live-mix + demux experience.
@@ -198,6 +259,7 @@ In addition there other reference implemetations that can be used:
198
259
  - `examples/drm.ts` : example with DRM
199
260
  - `examples/autocreate.ts` : example to auto create channel on demand
200
261
  - `examples/truncate.ts` : example when trimming start and end of a VOD
262
+ - `examples/adbreak.ts` : example with a channel configured for HLS-interstitial ad breaks
201
263
 
202
264
  ### Source linking hls-vodtolive library
203
265
 
@@ -1 +1 @@
1
- export function loadVod(p: any): Promise<any>;
1
+ export {};
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
2
3
  const debug = require('debug')('chaos-monkey');
3
4
  const CHAOS_MONKEY_PROBABILITY = process.env.CHAOS_MONKEY_PROBABILITY || 0.5;
4
5
  const doChaos = () => process.env.CHAOS_MONKEY === "true" && Math.random() < CHAOS_MONKEY_PROBABILITY;
@@ -1,6 +1 @@
1
- export = EventStream;
2
- declare class EventStream {
3
- constructor(session: any);
4
- _session: any;
5
- poll(): Promise<any>;
6
- }
1
+ export {};
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
2
3
  class EventStream {
4
+ _session;
3
5
  constructor(session) {
4
6
  this._session = session;
5
7
  }
@@ -1,13 +1 @@
1
- export = MemcachedStateStore;
2
- declare class MemcachedStateStore {
3
- constructor(keyPrefix: any, opts: any);
4
- keyPrefix: any;
5
- client: any;
6
- initAsync(id: any, initData: any): Promise<{}>;
7
- resetAsync(id: any, initData: any): Promise<void>;
8
- resetAllAsync(): Promise<void>;
9
- getAsync(id: any, key: any): Promise<any>;
10
- setAsync(id: any, key: any, value: any): Promise<any>;
11
- setVolatileAsync(id: any, key: any, value: any): Promise<void>;
12
- removeAsync(id: any, key: any): Promise<void>;
13
- }
1
+ export {};
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
2
3
  const MemcacheClient = require("memcache-client");
3
4
  const debug = require("debug")("memcached-state-store");
5
+ // Type-only migration (#373): a faithful port of the original JS.
4
6
  class MemcachedStateStore {
7
+ keyPrefix;
8
+ client;
5
9
  constructor(keyPrefix, opts) {
6
10
  this.keyPrefix = keyPrefix;
7
11
  if (opts.version) {
@@ -1,13 +1 @@
1
- export = MemoryStateStore;
2
- declare class MemoryStateStore {
3
- constructor(type: any, opts: any);
4
- sharedStates: {};
5
- globalSharedStates: {};
6
- initAsync(id: any, initData: any): Promise<any>;
7
- resetAsync(id: any, initData: any): Promise<void>;
8
- resetAllAsync(): Promise<void>;
9
- getAsync(id: any, key: any): Promise<any>;
10
- setAsync(id: any, key: any, value: any): Promise<any>;
11
- setVolatileAsync(id: any, key: any, value: any): Promise<any>;
12
- removeAsync(id: any, key: any): Promise<void>;
13
- }
1
+ export {};
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
2
3
  const debug = require("debug")("memory-state-store");
4
+ // Type-only migration (#373): a faithful port of the original JS. Runtime
5
+ // behavior and the exported constructor signature are unchanged.
3
6
  class MemoryStateStore {
7
+ sharedStates;
8
+ globalSharedStates;
4
9
  constructor(type, opts) {
5
10
  this.sharedStates = {};
6
11
  this.globalSharedStates = {};
@@ -1,27 +1 @@
1
- export const PlayheadState: Readonly<{
2
- RUNNING: 1;
3
- STOPPED: 2;
4
- CRASHED: 3;
5
- IDLE: 4;
6
- }>;
7
- export class PlayheadStateStore extends SharedStateStore {
8
- constructor(opts: any);
9
- create(sessionId: any): Promise<SharedPlayheadState>;
10
- }
11
- import SharedStateStore = require("./shared_state_store.js");
12
- declare class SharedPlayheadState {
13
- constructor(store: any, sessionId: any, opts: any);
14
- sessionId: any;
15
- store: any;
16
- state: 4;
17
- lastM3u8: any;
18
- get(key: any): Promise<any>;
19
- getState(): Promise<4>;
20
- getLastM3u8(): Promise<any>;
21
- getValues(keys: any): Promise<any>;
22
- set(key: any, value: any, isLeader: any): Promise<any>;
23
- setValues(keyValues: any, isLeader: any): Promise<any>;
24
- setState(newState: any): Promise<4>;
25
- setLastM3u8(m3u8: any): Promise<any>;
26
- }
27
1
  export {};
@@ -1,5 +1,10 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
2
3
  const SharedStateStore = require('./shared_state_store.js');
4
+ // Type-only migration (#373): a faithful port of the original JS.
5
+ // `SharedStateStore` is loaded via CommonJS `require` (erasable syntax) so the
6
+ // still-`.js` consumers keep resolving it unchanged; the base type is `any` at
7
+ // this interop boundary.
3
8
  const PlayheadState = Object.freeze({
4
9
  RUNNING: 1,
5
10
  STOPPED: 2,
@@ -7,6 +12,10 @@ const PlayheadState = Object.freeze({
7
12
  IDLE: 4
8
13
  });
9
14
  class SharedPlayheadState {
15
+ sessionId;
16
+ store;
17
+ state;
18
+ lastM3u8;
10
19
  constructor(store, sessionId, opts) {
11
20
  this.sessionId = sessionId;
12
21
  this.store = store;
@@ -1 +1 @@
1
- export function handler(req: any, res: any): Promise<void>;
1
+ export {};
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
2
3
  const constants = {
3
4
  ALLOW_HEADERS: [
4
5
  'accept',
@@ -1,19 +1 @@
1
- export = RedisStateStore;
2
- declare class RedisStateStore {
3
- constructor(keyPrefix: any, opts: any);
4
- keyPrefix: any;
5
- volatileKeyTTL: any;
6
- pool: any[];
7
- createRedisPool(size: any, redisUrl: any): any[];
8
- getClientFromPool(maxWaitTime?: number): Promise<any>;
9
- returnClientToPool(client: any): void;
10
- initAsync(id: any, initData: any): Promise<{}>;
11
- resetAsync(id: any, initData: any): Promise<void>;
12
- resetAllAsync(): Promise<void>;
13
- getValues(id: any, keys: any): Promise<{}>;
14
- getAsync(id: any, key: any): Promise<any>;
15
- setValues(id: any, data: any): Promise<{}>;
16
- setAsync(id: any, key: any, value: any): Promise<any>;
17
- setVolatileAsync(id: any, key: any, value: any): Promise<any>;
18
- removeAsync(id: any, key: any): Promise<any>;
19
- }
1
+ export {};
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
2
3
  const Redis = require("ioredis");
3
4
  const debug = require("debug")("redis-state-store");
4
5
  const { cloudWatchLog, timer } = require("./util.js");
6
+ // Type-only migration (#373): a faithful port of the original JS.
5
7
  const DEFAULT_VOLATILE_KEY_TTL = 5; // Timeout so it should not expire within one normal increment iteration (in seconds)
6
8
  function isTrue(s) {
7
9
  const regex = /^\s*(true|1)\s*$/i;
@@ -10,6 +12,9 @@ function isTrue(s) {
10
12
  const REDIS_VERBOSE_LOG = process.env.REDIS_VERBOSE_LOG ? isTrue(process.env.REDIS_VERBOSE_LOG) : false;
11
13
  const REDIS_POOL_SIZE = process.env.REDIS_POOL_SIZE ? parseInt(process.env.REDIS_POOL_SIZE) : 15;
12
14
  class RedisStateStore {
15
+ keyPrefix;
16
+ volatileKeyTTL;
17
+ pool;
13
18
  constructor(keyPrefix, opts) {
14
19
  this.keyPrefix = keyPrefix;
15
20
  if (opts.version) {
@@ -1,7 +1,18 @@
1
+ export interface AdBreakOpts {
2
+ enabled: boolean;
3
+ adServerUri?: string;
4
+ slate?: SlateOpts;
5
+ }
6
+ export interface SlateOpts {
7
+ uri: string;
8
+ repetitions?: number;
9
+ duration?: number;
10
+ }
1
11
  export interface ChannelEngineOpts {
2
12
  defaultSlateUri?: string;
3
13
  slateRepetitions?: number;
4
14
  slateDuration?: number;
15
+ adBreak?: AdBreakOpts;
5
16
  redisUrl?: string;
6
17
  memcachedUrl?: string;
7
18
  sharedStoreCacheTTL?: number;
@@ -35,11 +46,19 @@ export interface ChannelEngineOpts {
35
46
  sessionEventStream?: boolean;
36
47
  sessionHealthKey?: string;
37
48
  rollingPDT?: boolean;
49
+ event?: boolean;
50
+ customVodRequestParams?: string[];
51
+ streamSwitchTimeIntervalMs?: number;
52
+ streamSwitchOngoingEventIntervalMs?: number;
53
+ streamSwitchNearEndEventIntervalMs?: number;
38
54
  }
39
55
  export interface VodRequest {
40
56
  sessionId: string;
41
57
  category?: string;
42
58
  playlistId: string;
59
+ customParams?: {
60
+ [key: string]: string;
61
+ };
43
62
  }
44
63
  export interface VodResponseMetadata {
45
64
  id: string;
@@ -86,6 +105,8 @@ export interface Channel {
86
105
  audioTracks?: AudioTracks[];
87
106
  subtitleTracks?: SubtitleTracks[];
88
107
  closedCaptions?: ClosedCaptions[];
108
+ slate?: SlateOpts;
109
+ adBreak?: AdBreakOpts;
89
110
  }
90
111
  export interface ClosedCaptions {
91
112
  id: string;
@@ -138,6 +159,7 @@ export declare class ChannelEngine {
138
159
  private alwaysMapBandwidthByNearest;
139
160
  private defaultSlateUri?;
140
161
  private slateDuration?;
162
+ private adBreak?;
141
163
  private assetMgr;
142
164
  private streamSwitchManager?;
143
165
  private slateRepetitions?;
@@ -146,6 +168,8 @@ export declare class ChannelEngine {
146
168
  private serverStartTime;
147
169
  private instanceId;
148
170
  private streamSwitchTimeIntervalMs;
171
+ private streamSwitchOngoingEventIntervalMs;
172
+ private streamSwitchNearEndEventIntervalMs;
149
173
  private sessionStore;
150
174
  private sessionLiveStore;
151
175
  private streamerOpts;
@@ -156,7 +180,10 @@ export declare class ChannelEngine {
156
180
  private sessionResetKey;
157
181
  private sessionEventStream;
158
182
  private sessionHealthKey;
183
+ private customVodRequestParams;
184
+ private static normalizeAdBreak;
159
185
  constructor(assetMgr: IAssetManager, options?: ChannelEngineOpts);
186
+ computeStreamSwitchIntervalMs(baseIntervalMs: any): any;
160
187
  updateStreamSwitchAsync(): Promise<void>;
161
188
  updateChannelsAsync(channelMgr: any, options: any): Promise<void>;
162
189
  start(): void;