@norskvideo/norsk-studio-built-ins 1.11.6 → 1.12.0-2025-01-28-397642d6
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/README.md +16 -0
- package/client/info.js +1402 -782
- package/client/output.whep/styles.css +9 -0
- package/client/style.css +520 -858
- package/lib/info.js +4 -8
- package/lib/info.js.map +1 -1
- package/lib/input.rtmp/info.js +2 -1
- package/lib/input.rtmp/info.js.map +1 -1
- package/lib/input.rtmp/runtime.d.ts +24 -5
- package/lib/input.rtmp/runtime.js +166 -60
- package/lib/input.rtmp/runtime.js.map +1 -1
- package/lib/input.rtmp/summary-view.d.ts +3 -5
- package/lib/input.rtmp/summary-view.js +26 -6
- package/lib/input.rtmp/summary-view.js.map +1 -1
- package/lib/input.rtmp/types.d.ts +133 -0
- package/lib/input.rtmp/types.js +3 -0
- package/lib/input.rtmp/types.js.map +1 -0
- package/lib/input.rtmp/types.yaml +99 -0
- package/lib/input.silence/info.js +3 -2
- package/lib/input.silence/info.js.map +1 -1
- package/lib/input.srt-caller/info.js +6 -5
- package/lib/input.srt-caller/info.js.map +1 -1
- package/lib/input.srt-caller/runtime.d.ts +1 -1
- package/lib/input.srt-listener/info.js +14 -6
- package/lib/input.srt-listener/info.js.map +1 -1
- package/lib/input.srt-listener/runtime.d.ts +42 -6
- package/lib/input.srt-listener/runtime.js +237 -57
- package/lib/input.srt-listener/runtime.js.map +1 -1
- package/lib/input.srt-listener/summary-view.d.ts +3 -5
- package/lib/input.srt-listener/summary-view.js +81 -5
- package/lib/input.srt-listener/summary-view.js.map +1 -1
- package/lib/input.srt-listener/types.d.ts +193 -0
- package/lib/input.srt-listener/types.js +3 -0
- package/lib/input.srt-listener/types.js.map +1 -0
- package/lib/input.srt-listener/types.yaml +145 -0
- package/lib/input.udp-ts/info.d.ts +1 -1
- package/lib/input.udp-ts/info.js +5 -4
- package/lib/input.udp-ts/info.js.map +1 -1
- package/lib/input.udp-ts/runtime.d.ts +1 -1
- package/lib/input.videoTestCard/info.d.ts +1 -1
- package/lib/input.videoTestCard/info.js +14 -4
- package/lib/input.videoTestCard/info.js.map +1 -1
- package/lib/output.autoCmaf/info.d.ts +2 -2
- package/lib/output.autoCmaf/info.js +65 -7
- package/lib/output.autoCmaf/info.js.map +1 -1
- package/lib/output.autoCmaf/runtime.d.ts +29 -9
- package/lib/output.autoCmaf/runtime.js +198 -60
- package/lib/output.autoCmaf/runtime.js.map +1 -1
- package/lib/output.autoCmaf/summary.js +26 -1
- package/lib/output.autoCmaf/summary.js.map +1 -1
- package/lib/output.autoCmaf/types.d.ts +101 -0
- package/lib/output.autoCmaf/types.js +3 -0
- package/lib/output.autoCmaf/types.js.map +1 -0
- package/lib/output.autoCmaf/types.yaml +28 -0
- package/lib/output.preview/info.js +5 -2
- package/lib/output.preview/info.js.map +1 -1
- package/lib/output.preview/inline-view.d.ts +2 -4
- package/lib/output.preview/inline-view.js +41 -7
- package/lib/output.preview/inline-view.js.map +1 -1
- package/lib/output.preview/runtime.d.ts +5 -3
- package/lib/output.preview/runtime.js +29 -18
- package/lib/output.preview/runtime.js.map +1 -1
- package/lib/output.rtmp/info.js +1 -0
- package/lib/output.rtmp/info.js.map +1 -1
- package/lib/output.rtmp/inline-view.js +2 -2
- package/lib/output.rtmp/runtime.d.ts +2 -2
- package/lib/output.rtmp/runtime.js.map +1 -1
- package/lib/output.srt/info.d.ts +2 -2
- package/lib/output.srt/info.js +26 -5
- package/lib/output.srt/info.js.map +1 -1
- package/lib/output.srt/runtime.d.ts +30 -5
- package/lib/output.srt/runtime.js +139 -5
- package/lib/output.srt/runtime.js.map +1 -1
- package/lib/output.srt/types.d.ts +101 -0
- package/lib/output.srt/types.js +3 -0
- package/lib/output.srt/types.js.map +1 -0
- package/lib/output.srt/types.yaml +31 -0
- package/lib/output.statistics/info.js +1 -0
- package/lib/output.statistics/info.js.map +1 -1
- package/lib/output.statistics/inline-view.js +3 -2
- package/lib/output.statistics/inline-view.js.map +1 -1
- package/lib/output.statistics/runtime.d.ts +1 -1
- package/lib/output.statistics/runtime.js.map +1 -1
- package/lib/output.udpTs/info.d.ts +1 -1
- package/lib/output.udpTs/info.js +4 -3
- package/lib/output.udpTs/info.js.map +1 -1
- package/lib/output.udpTs/runtime.d.ts +1 -1
- package/lib/output.whep/info.d.ts +2 -2
- package/lib/output.whep/info.js +50 -1
- package/lib/output.whep/info.js.map +1 -1
- package/lib/output.whep/inline-view.d.ts +4 -0
- package/lib/output.whep/inline-view.js +57 -0
- package/lib/output.whep/inline-view.js.map +1 -0
- package/lib/output.whep/runtime.d.ts +27 -5
- package/lib/output.whep/runtime.js +64 -13
- package/lib/output.whep/runtime.js.map +1 -1
- package/lib/output.whep/types.d.ts +101 -0
- package/lib/output.whep/types.js +3 -0
- package/lib/output.whep/types.js.map +1 -0
- package/lib/output.whep/types.yaml +30 -0
- package/lib/processor.browserOverlay/info.d.ts +2 -2
- package/lib/processor.browserOverlay/info.js +56 -2
- package/lib/processor.browserOverlay/info.js.map +1 -1
- package/lib/processor.browserOverlay/inline-view.d.ts +6 -0
- package/lib/processor.browserOverlay/inline-view.js +8 -0
- package/lib/processor.browserOverlay/inline-view.js.map +1 -0
- package/lib/processor.browserOverlay/runtime.d.ts +40 -6
- package/lib/processor.browserOverlay/runtime.js +151 -23
- package/lib/processor.browserOverlay/runtime.js.map +1 -1
- package/lib/processor.browserOverlay/summary-view.d.ts +4 -0
- package/lib/processor.browserOverlay/summary-view.js +27 -0
- package/lib/processor.browserOverlay/summary-view.js.map +1 -0
- package/lib/processor.browserOverlay/types.d.ts +174 -0
- package/lib/processor.browserOverlay/types.js +3 -0
- package/lib/processor.browserOverlay/types.js.map +1 -0
- package/lib/processor.browserOverlay/types.yaml +65 -0
- package/lib/processor.cascadingSwitch/info.js +4 -3
- package/lib/processor.cascadingSwitch/info.js.map +1 -1
- package/lib/processor.cascadingSwitch/inline-view.js +3 -3
- package/lib/processor.cascadingSwitch/runtime.d.ts +1 -1
- package/lib/processor.cascadingSwitch/runtime.js +2 -2
- package/lib/processor.cascadingSwitch/runtime.js.map +1 -1
- package/lib/processor.fixedLadder/codec-editor.js +1 -1
- package/lib/processor.fixedLadder/codec-editor.js.map +1 -1
- package/lib/processor.fixedLadder/codec-view.js +1 -1
- package/lib/processor.fixedLadder/codec-view.js.map +1 -1
- package/lib/processor.fixedLadder/info.js +4 -2
- package/lib/processor.fixedLadder/info.js.map +1 -1
- package/lib/processor.fixedLadder/rung-view.js +1 -1
- package/lib/processor.fixedLadder/rung-view.js.map +1 -1
- package/lib/processor.onscreenGraphic/image-selection.d.ts +9 -0
- package/lib/{processor.dynamicBug/bug-selection.js → processor.onscreenGraphic/image-selection.js} +10 -10
- package/lib/processor.onscreenGraphic/image-selection.js.map +1 -0
- package/lib/processor.onscreenGraphic/info.d.ts +3 -0
- package/lib/{processor.dynamicBug → processor.onscreenGraphic}/info.js +23 -16
- package/lib/processor.onscreenGraphic/info.js.map +1 -0
- package/lib/processor.onscreenGraphic/runtime.d.ts +91 -0
- package/lib/processor.onscreenGraphic/runtime.js +503 -0
- package/lib/processor.onscreenGraphic/runtime.js.map +1 -0
- package/lib/processor.onscreenGraphic/summary-view.d.ts +4 -0
- package/lib/processor.onscreenGraphic/summary-view.js +343 -0
- package/lib/processor.onscreenGraphic/summary-view.js.map +1 -0
- package/lib/processor.onscreenGraphic/types.d.ts +271 -0
- package/lib/processor.onscreenGraphic/types.js +3 -0
- package/lib/processor.onscreenGraphic/types.js.map +1 -0
- package/lib/processor.onscreenGraphic/types.yaml +211 -0
- package/lib/processor.streamKeyOverride/info.d.ts +3 -0
- package/lib/processor.streamKeyOverride/info.js +150 -0
- package/lib/processor.streamKeyOverride/info.js.map +1 -0
- package/lib/processor.streamKeyOverride/runtime.d.ts +54 -0
- package/lib/processor.streamKeyOverride/runtime.js +226 -0
- package/lib/processor.streamKeyOverride/runtime.js.map +1 -0
- package/lib/shared/drm/axinom.d.ts +2 -0
- package/lib/shared/drm/axinom.js +120 -0
- package/lib/shared/drm/axinom.js.map +1 -0
- package/lib/shared/drm/cpix.d.ts +24 -0
- package/lib/shared/drm/cpix.js +97 -0
- package/lib/shared/drm/cpix.js.map +1 -0
- package/lib/shared/drm/ezdrm.d.ts +2 -0
- package/lib/shared/drm/ezdrm.js +26 -0
- package/lib/shared/drm/ezdrm.js.map +1 -0
- package/lib/shared/srt-socket-options.js +6 -6
- package/lib/shared/srt-socket-options.js.map +1 -1
- package/lib/test/auto-cmaf.js +25 -17
- package/lib/test/auto-cmaf.js.map +1 -1
- package/lib/test/browser-overlay.js +1 -0
- package/lib/test/browser-overlay.js.map +1 -1
- package/lib/test/{dynamic-bug.js → onscreen-graphic.js} +139 -106
- package/lib/test/onscreen-graphic.js.map +1 -0
- package/lib/test/preview.js +3 -3
- package/lib/test/preview.js.map +1 -1
- package/lib/test/rtmp-input.js +6 -3
- package/lib/test/rtmp-input.js.map +1 -1
- package/lib/test/srt-input-caller.js +5 -5
- package/lib/test/srt-input-caller.js.map +1 -1
- package/lib/test/srt-input-listener.js +99 -18
- package/lib/test/srt-input-listener.js.map +1 -1
- package/lib/test/srt-output.js +2 -2
- package/lib/test/srt-output.js.map +1 -1
- package/lib/test/udp-output.js +2 -2
- package/lib/test/udp-output.js.map +1 -1
- package/lib/test/udp-ts-input.js +2 -2
- package/lib/test/udp-ts-input.js.map +1 -1
- package/lib/test/whep-output.js +8 -2
- package/lib/test/whep-output.js.map +1 -1
- package/lib/{util.latency → util.stats.latency}/info.js +2 -1
- package/lib/util.stats.latency/info.js.map +1 -0
- package/lib/util.stats.latency/inline-view.js.map +1 -0
- package/lib/{util.latency → util.stats.latency}/runtime.d.ts +1 -1
- package/lib/{util.latency → util.stats.latency}/runtime.js +2 -2
- package/lib/util.stats.latency/runtime.js.map +1 -0
- package/lib/util.stats.latency/source-node-selection.js.map +1 -0
- package/package.json +12 -5
- package/lib/processor.dynamicBug/bug-selection.d.ts +0 -9
- package/lib/processor.dynamicBug/bug-selection.js.map +0 -1
- package/lib/processor.dynamicBug/info.d.ts +0 -3
- package/lib/processor.dynamicBug/info.js.map +0 -1
- package/lib/processor.dynamicBug/runtime.d.ts +0 -64
- package/lib/processor.dynamicBug/runtime.js +0 -297
- package/lib/processor.dynamicBug/runtime.js.map +0 -1
- package/lib/processor.dynamicBug/summary-view.d.ts +0 -4
- package/lib/processor.dynamicBug/summary-view.js +0 -60
- package/lib/processor.dynamicBug/summary-view.js.map +0 -1
- package/lib/processor.whisper-transcribe/info.d.ts +0 -3
- package/lib/processor.whisper-transcribe/info.js +0 -43
- package/lib/processor.whisper-transcribe/info.js.map +0 -1
- package/lib/processor.whisper-transcribe/runtime.d.ts +0 -29
- package/lib/processor.whisper-transcribe/runtime.js +0 -83
- package/lib/processor.whisper-transcribe/runtime.js.map +0 -1
- package/lib/test/dynamic-bug.js.map +0 -1
- package/lib/util.latency/info.js.map +0 -1
- package/lib/util.latency/inline-view.js.map +0 -1
- package/lib/util.latency/runtime.js.map +0 -1
- package/lib/util.latency/source-node-selection.js.map +0 -1
- package/lib/util.ma35d/info.d.ts +0 -3
- package/lib/util.ma35d/info.js +0 -78
- package/lib/util.ma35d/info.js.map +0 -1
- package/lib/util.ma35d/inline-view.d.ts +0 -6
- package/lib/util.ma35d/inline-view.js +0 -76
- package/lib/util.ma35d/inline-view.js.map +0 -1
- package/lib/util.ma35d/runtime.d.ts +0 -21
- package/lib/util.ma35d/runtime.js +0 -49
- package/lib/util.ma35d/runtime.js.map +0 -1
- package/lib/util.timestamps/info.d.ts +0 -5
- package/lib/util.timestamps/info.js +0 -86
- package/lib/util.timestamps/info.js.map +0 -1
- package/lib/util.timestamps/inline-view.d.ts +0 -6
- package/lib/util.timestamps/inline-view.js +0 -94
- package/lib/util.timestamps/inline-view.js.map +0 -1
- package/lib/util.timestamps/runtime.d.ts +0 -29
- package/lib/util.timestamps/runtime.js +0 -40
- package/lib/util.timestamps/runtime.js.map +0 -1
- /package/lib/test/{dynamic-bug.d.ts → onscreen-graphic.d.ts} +0 -0
- /package/lib/{util.latency → util.stats.latency}/info.d.ts +0 -0
- /package/lib/{util.latency → util.stats.latency}/inline-view.d.ts +0 -0
- /package/lib/{util.latency → util.stats.latency}/inline-view.js +0 -0
- /package/lib/{util.latency → util.stats.latency}/source-node-selection.d.ts +0 -0
- /package/lib/{util.latency → util.stats.latency}/source-node-selection.js +0 -0
@@ -27,9 +27,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
27
27
|
};
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
29
29
|
exports.default = default_1;
|
30
|
+
const config_1 = require("@norskvideo/norsk-studio/lib/shared/config");
|
30
31
|
const react_1 = __importDefault(require("react"));
|
31
|
-
function default_1(
|
32
|
-
const
|
32
|
+
function default_1(R) {
|
33
|
+
const { defineComponent, All, validation: { Z, Hostname }, } = R;
|
33
34
|
const FullscreenView = react_1.default.lazy(async () => Promise.resolve().then(() => __importStar(require('./fullscreen'))));
|
34
35
|
const SegmentConfiguration = react_1.default.lazy(async () => {
|
35
36
|
const views = await Promise.resolve().then(() => __importStar(require('./form-views')));
|
@@ -43,6 +44,7 @@ function default_1({ defineComponent, All, validation: { Z, Hostname }, }) {
|
|
43
44
|
identifier: 'output.autoCmaf',
|
44
45
|
category: 'output',
|
45
46
|
name: "Auto CMAF",
|
47
|
+
description: "This component handles the creation of CMAF outputs from multiple video and audio streams.",
|
46
48
|
subscription: {
|
47
49
|
accepts: {
|
48
50
|
type: "multi-stream",
|
@@ -50,10 +52,36 @@ function default_1({ defineComponent, All, validation: { Z, Hostname }, }) {
|
|
50
52
|
}
|
51
53
|
},
|
52
54
|
extraValidation: (ctx) => {
|
53
|
-
const audioStreams = ctx.subscriptions.filter((s) => s.
|
55
|
+
const audioStreams = ctx.subscriptions.filter((s) => s.validatedStreams.select.includes("audio"));
|
54
56
|
if (audioStreams.length == 0) {
|
55
57
|
ctx.addError("AutoCMAF requires at least one audio stream");
|
56
58
|
}
|
59
|
+
const uniqueVideoStreamNodes = ctx.subscriptions.reduce((acc, s) => {
|
60
|
+
if (s.validatedStreams.select.includes("video")) {
|
61
|
+
if (!acc.includes(s.source)) {
|
62
|
+
acc.push(s.source);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
return acc;
|
66
|
+
}, []);
|
67
|
+
if (uniqueVideoStreamNodes.length > 1) {
|
68
|
+
ctx.addWarning("More than one video source detected, did you mean to do this? (For example: Did you subscribe to both a source *and* a ladder?)");
|
69
|
+
}
|
70
|
+
if (ctx.config.drmProvider && ctx.config.__global) {
|
71
|
+
if (ctx.config.drmProvider === 'ezdrm') {
|
72
|
+
if (!ctx.config.__global.ezdrmConfig?.token) {
|
73
|
+
ctx.addError("Provide EZDRM token in global configuration");
|
74
|
+
}
|
75
|
+
}
|
76
|
+
if (ctx.config.drmProvider === 'axinom') {
|
77
|
+
if (!ctx.config.__global.axinomConfig?.tenantId) {
|
78
|
+
ctx.addError("Provide Axinom DRM Tenant ID in global configuration");
|
79
|
+
}
|
80
|
+
if (!ctx.config.__global.axinomConfig?.managementKey) {
|
81
|
+
ctx.addError("Provide Axinom DRM Management Key in global configuration");
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
57
85
|
},
|
58
86
|
display: (desc) => {
|
59
87
|
return {
|
@@ -61,22 +89,34 @@ function default_1({ defineComponent, All, validation: { Z, Hostname }, }) {
|
|
61
89
|
};
|
62
90
|
},
|
63
91
|
runtime: {
|
64
|
-
initialState: () => ({
|
92
|
+
initialState: () => ({
|
93
|
+
enabled: true,
|
94
|
+
}),
|
65
95
|
handleEvent(ev, state) {
|
66
96
|
const evType = ev.type;
|
67
97
|
switch (evType) {
|
68
98
|
case 'url-published':
|
69
99
|
state.url = ev.url;
|
100
|
+
state.drmToken = ev.drmToken;
|
101
|
+
break;
|
102
|
+
case 'output-enabled':
|
103
|
+
state.enabled = true;
|
104
|
+
break;
|
105
|
+
case 'output-disabled':
|
106
|
+
state.enabled = false;
|
70
107
|
break;
|
71
108
|
default:
|
72
109
|
assertUnreachable(evType);
|
73
110
|
}
|
74
111
|
return { ...state };
|
75
112
|
},
|
76
|
-
summary: SummaryView,
|
77
113
|
fullscreen: FullscreenView
|
78
114
|
},
|
79
115
|
configForm: {
|
116
|
+
global: {
|
117
|
+
ezdrmConfig: (0, config_1.GlobalEzDrmConfig)(R),
|
118
|
+
axinomConfig: (0, config_1.GlobalAxinomConfig)(R),
|
119
|
+
},
|
80
120
|
form: {
|
81
121
|
name: {
|
82
122
|
help: "The name of the multivariant/dash playlist",
|
@@ -142,6 +182,7 @@ function default_1({ defineComponent, All, validation: { Z, Hostname }, }) {
|
|
142
182
|
help: "How many segments back should a player start",
|
143
183
|
hint: {
|
144
184
|
type: "numeric",
|
185
|
+
optional: true,
|
145
186
|
validation: Z.number().min(3).max(10).int().optional(),
|
146
187
|
},
|
147
188
|
},
|
@@ -149,6 +190,7 @@ function default_1({ defineComponent, All, validation: { Z, Hostname }, }) {
|
|
149
190
|
help: "How many parts back should a player start",
|
150
191
|
hint: {
|
151
192
|
type: "numeric",
|
193
|
+
optional: true,
|
152
194
|
validation: Z.number().min(3).max(10).int().optional(),
|
153
195
|
},
|
154
196
|
},
|
@@ -166,12 +208,11 @@ function default_1({ defineComponent, All, validation: { Z, Hostname }, }) {
|
|
166
208
|
help: "The hostname of the s3 bucket to push to",
|
167
209
|
hint: {
|
168
210
|
type: "text",
|
169
|
-
defaultValue: "",
|
170
211
|
validation: Hostname
|
171
212
|
}
|
172
213
|
},
|
173
214
|
prefix: {
|
174
|
-
help: "The sub directory of the bucket to place playlists
|
215
|
+
help: "The sub directory of the bucket to place playlists and segments into",
|
175
216
|
hint: {
|
176
217
|
type: "text",
|
177
218
|
defaultValue: ""
|
@@ -187,6 +228,23 @@ function default_1({ defineComponent, All, validation: { Z, Hostname }, }) {
|
|
187
228
|
}
|
188
229
|
}
|
189
230
|
},
|
231
|
+
drmProvider: {
|
232
|
+
help: "Encrypt with a DRM provider (if configured globally)",
|
233
|
+
hint: {
|
234
|
+
type: 'select',
|
235
|
+
optional: true,
|
236
|
+
options: [
|
237
|
+
{
|
238
|
+
display: "EZDRM",
|
239
|
+
value: 'ezdrm',
|
240
|
+
},
|
241
|
+
{
|
242
|
+
display: "Axinom DRM",
|
243
|
+
value: 'axinom',
|
244
|
+
},
|
245
|
+
],
|
246
|
+
},
|
247
|
+
},
|
190
248
|
}
|
191
249
|
}
|
192
250
|
});
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"info.js","sourceRoot":"","sources":["../../src/output.autoCmaf/info.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
1
|
+
{"version":3,"file":"info.js","sourceRoot":"","sources":["../../src/output.autoCmaf/info.ts"],"names":[],"mappings":"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"}
|
@@ -1,7 +1,10 @@
|
|
1
|
-
import { AdMarker, AutoProcessorMediaNode, CmafDestinationSettings, CmafMultiVariantOutputNode, Norsk, StreamKey
|
2
|
-
import { CreatedMediaNode, OnCreated, ServerComponentDefinition, StudioNodeSubscriptionSource, StudioRuntime } from '@norskvideo/norsk-studio/lib/extension/runtime-types';
|
1
|
+
import { AdMarker, AutoProcessorMediaNode, CmafDestinationSettings, CmafMultiVariantOutputNode, Norsk, StreamKey } from '@norskvideo/norsk-sdk';
|
2
|
+
import { CreatedMediaNode, InstanceRouteInfo, OnCreated, ServerComponentDefinition, StudioNodeSubscriptionSource, StudioRuntime } from '@norskvideo/norsk-studio/lib/extension/runtime-types';
|
3
3
|
import { CustomSinkNode } from '@norskvideo/norsk-studio/lib/extension/base-nodes';
|
4
4
|
import { ReportBuilder } from '@norskvideo/norsk-studio/lib/runtime/execution';
|
5
|
+
import { AxinomConfig, EzDrmConfig } from '@norskvideo/norsk-studio/lib/shared/config';
|
6
|
+
import { CryptoDetails } from '../shared/drm/cpix';
|
7
|
+
import { ContextPromiseControl } from '@norskvideo/norsk-studio/lib/runtime/util';
|
5
8
|
export type AutoCmafS3Destination = {
|
6
9
|
host: string;
|
7
10
|
prefix: string;
|
@@ -14,6 +17,11 @@ export type AutoCmafConfig = {
|
|
14
17
|
sessionId: boolean;
|
15
18
|
segments: AutoCmafSegment;
|
16
19
|
s3Destinations: AutoCmafS3Destination[];
|
20
|
+
drmProvider?: 'ezdrm' | 'axinom';
|
21
|
+
__global: {
|
22
|
+
ezdrmConfig?: EzDrmConfig;
|
23
|
+
axinomConfig?: AxinomConfig;
|
24
|
+
};
|
17
25
|
};
|
18
26
|
export type AutoCmafSegment = {
|
19
27
|
retentionPeriod: number;
|
@@ -25,24 +33,33 @@ export type AutoCmafSegment = {
|
|
25
33
|
};
|
26
34
|
export type CmafOutputState = {
|
27
35
|
url?: string;
|
36
|
+
drmToken?: string;
|
37
|
+
enabled: boolean;
|
28
38
|
};
|
29
39
|
export type CmafOutputEvent = {
|
30
|
-
type: 'url-published';
|
40
|
+
type: 'url-published' | 'output-enabled' | 'output-disabled';
|
31
41
|
url: string;
|
42
|
+
drmToken?: string;
|
43
|
+
};
|
44
|
+
export type CmafOutputCommand = {
|
45
|
+
type: 'enable-output' | 'disable-output';
|
32
46
|
};
|
33
|
-
export type CmafOutputCommand = object;
|
34
47
|
export default class AutoCmafDefinition implements ServerComponentDefinition<AutoCmafConfig, AutoCmaf, CmafOutputState, CmafOutputCommand, CmafOutputEvent> {
|
35
|
-
create(norsk: Norsk, cfg: AutoCmafConfig, cb: OnCreated<AutoCmaf>, { updates, report }: StudioRuntime<CmafOutputState, CmafOutputEvent>): Promise<void>;
|
48
|
+
create(norsk: Norsk, cfg: AutoCmafConfig, cb: OnCreated<AutoCmaf>, { updates, report }: StudioRuntime<CmafOutputState, CmafOutputCommand, CmafOutputEvent>): Promise<void>;
|
49
|
+
handleCommand(node: AutoCmaf, command: CmafOutputCommand): Promise<void>;
|
50
|
+
instanceRoutes(): Promise<InstanceRouteInfo<AutoCmafConfig, AutoCmaf, CmafOutputState, CmafOutputCommand, CmafOutputEvent>[]>;
|
36
51
|
}
|
37
52
|
export declare class AutoCmaf extends CustomSinkNode {
|
38
53
|
norsk: Norsk;
|
39
54
|
cfg: AutoCmafConfig;
|
40
55
|
currentSources: Map<CreatedMediaNode, StudioNodeSubscriptionSource>;
|
41
56
|
currentMedia: {
|
42
|
-
node
|
57
|
+
node: AutoProcessorMediaNode<string>;
|
43
58
|
key: StreamKey;
|
44
59
|
scheduleAd: (marker: AdMarker, destinationId: string) => void;
|
45
60
|
}[];
|
61
|
+
crypto?: CryptoDetails;
|
62
|
+
control: ContextPromiseControl;
|
46
63
|
mv?: CmafMultiVariantOutputNode;
|
47
64
|
defaultProgramNumber: number;
|
48
65
|
defaultSourceName: string;
|
@@ -51,16 +68,19 @@ export declare class AutoCmaf extends CustomSinkNode {
|
|
51
68
|
programNumber: number;
|
52
69
|
sourceName: string;
|
53
70
|
}[];
|
54
|
-
pendingResponses: ((error?: SubscriptionError) => void)[];
|
55
71
|
initialised: Promise<void>;
|
56
72
|
sessionId?: string;
|
57
73
|
destinations: CmafDestinationSettings[];
|
58
74
|
advertDestinations: string[];
|
59
75
|
report: ReportBuilder;
|
76
|
+
enabled: boolean;
|
77
|
+
nodeCounter: number;
|
60
78
|
static create(norsk: Norsk, cfg: AutoCmafConfig, report: ReportBuilder): Promise<AutoCmaf>;
|
61
79
|
constructor(cfg: AutoCmafConfig, norsk: Norsk, report: ReportBuilder);
|
62
80
|
initialise(): Promise<void>;
|
63
|
-
|
64
|
-
|
81
|
+
incrementNodeId(id: string): string;
|
82
|
+
enableOutput(): Promise<void>;
|
83
|
+
disableOutput(): Promise<void>;
|
84
|
+
handleContext(): Promise<void>;
|
65
85
|
subscribe(subs: StudioNodeSubscriptionSource[]): void;
|
66
86
|
}
|
@@ -1,10 +1,35 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
6
|
exports.AutoCmaf = void 0;
|
4
7
|
const norsk_sdk_1 = require("@norskvideo/norsk-sdk");
|
5
8
|
const util_1 = require("@norskvideo/norsk-studio/lib/shared/util");
|
6
9
|
const base_nodes_1 = require("@norskvideo/norsk-studio/lib/extension/base-nodes");
|
7
10
|
const logging_1 = require("@norskvideo/norsk-studio/lib/server/logging");
|
11
|
+
const ezdrm_1 = require("../shared/drm/ezdrm");
|
12
|
+
const axinom_1 = require("../shared/drm/axinom");
|
13
|
+
const util_2 = require("@norskvideo/norsk-studio/lib/runtime/util");
|
14
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
15
|
+
const json_refs_1 = require("json-refs");
|
16
|
+
const path_1 = __importDefault(require("path"));
|
17
|
+
const yaml_1 = __importDefault(require("yaml"));
|
18
|
+
function coreInfo(path, op) {
|
19
|
+
return {
|
20
|
+
url: path,
|
21
|
+
summary: op.summary,
|
22
|
+
description: op.description,
|
23
|
+
requestBody: op.requestBody,
|
24
|
+
responses: op.responses,
|
25
|
+
};
|
26
|
+
}
|
27
|
+
function post(path, paths) {
|
28
|
+
return {
|
29
|
+
...coreInfo(path, paths[path]['post']),
|
30
|
+
method: 'POST',
|
31
|
+
};
|
32
|
+
}
|
8
33
|
class AutoCmafDefinition {
|
9
34
|
async create(norsk, cfg, cb, { updates, report }) {
|
10
35
|
const node = await AutoCmaf.create(norsk, cfg, report);
|
@@ -12,9 +37,77 @@ class AutoCmafDefinition {
|
|
12
37
|
const mv = node.mv;
|
13
38
|
if (mv) {
|
14
39
|
report.registerOutput(cfg.id, mv.url);
|
15
|
-
updates.raiseEvent({ type: 'url-published', url: mv.url });
|
40
|
+
updates.raiseEvent({ type: 'url-published', url: mv.url, drmToken: node.crypto?.token });
|
41
|
+
}
|
42
|
+
}
|
43
|
+
async handleCommand(node, command) {
|
44
|
+
switch (command.type) {
|
45
|
+
case 'enable-output':
|
46
|
+
await node.enableOutput();
|
47
|
+
break;
|
48
|
+
case 'disable-output':
|
49
|
+
await node.disableOutput();
|
50
|
+
break;
|
51
|
+
default:
|
52
|
+
(0, util_1.assertUnreachable)(command.type);
|
16
53
|
}
|
17
54
|
}
|
55
|
+
async instanceRoutes() {
|
56
|
+
const types = await promises_1.default.readFile(path_1.default.join(__dirname, 'types.yaml'));
|
57
|
+
const root = yaml_1.default.parse(types.toString());
|
58
|
+
const resolved = await (0, json_refs_1.resolveRefs)(root, {}).then((r) => r.resolved);
|
59
|
+
const paths = resolved.paths;
|
60
|
+
return [
|
61
|
+
{
|
62
|
+
...post('/enable', paths),
|
63
|
+
handler: ({ runtime }) => async (_req, res) => {
|
64
|
+
try {
|
65
|
+
const state = runtime.updates.latest();
|
66
|
+
if (state.enabled) {
|
67
|
+
return res.status(400).json({ error: 'Output is already enabled' });
|
68
|
+
}
|
69
|
+
runtime.updates.update({ ...state, enabled: true });
|
70
|
+
runtime.updates.sendCommand({
|
71
|
+
type: 'enable-output'
|
72
|
+
});
|
73
|
+
runtime.updates.raiseEvent({
|
74
|
+
type: 'output-enabled',
|
75
|
+
url: state.url ?? '',
|
76
|
+
});
|
77
|
+
res.sendStatus(204);
|
78
|
+
}
|
79
|
+
catch (error) {
|
80
|
+
console.error('Error in enable handler:', error);
|
81
|
+
res.status(500).json({ error: 'Failed to enable output' });
|
82
|
+
}
|
83
|
+
}
|
84
|
+
},
|
85
|
+
{
|
86
|
+
...post('/disable', paths),
|
87
|
+
handler: ({ runtime }) => async (_req, res) => {
|
88
|
+
try {
|
89
|
+
const state = runtime.updates.latest();
|
90
|
+
if (!state.enabled) {
|
91
|
+
return res.status(400).json({ error: 'Output is already disabled' });
|
92
|
+
}
|
93
|
+
runtime.updates.update({ ...state, enabled: false });
|
94
|
+
runtime.updates.sendCommand({
|
95
|
+
type: 'disable-output'
|
96
|
+
});
|
97
|
+
runtime.updates.raiseEvent({
|
98
|
+
type: 'output-disabled',
|
99
|
+
url: state.url ?? '',
|
100
|
+
});
|
101
|
+
res.sendStatus(204);
|
102
|
+
}
|
103
|
+
catch (error) {
|
104
|
+
console.error('Error in disable handler:', error);
|
105
|
+
res.status(500).json({ error: 'Failed to disable output' });
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
];
|
110
|
+
}
|
18
111
|
}
|
19
112
|
exports.default = AutoCmafDefinition;
|
20
113
|
class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
@@ -22,16 +115,19 @@ class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
|
22
115
|
cfg;
|
23
116
|
currentSources = new Map();
|
24
117
|
currentMedia = [];
|
118
|
+
crypto;
|
119
|
+
control = new util_2.ContextPromiseControl(this.handleContext.bind(this));
|
25
120
|
mv;
|
26
121
|
defaultProgramNumber = 0;
|
27
122
|
defaultSourceName = '';
|
28
123
|
currentMultiVariants = [];
|
29
|
-
pendingResponses = [];
|
30
124
|
initialised;
|
31
125
|
sessionId;
|
32
126
|
destinations;
|
33
127
|
advertDestinations = [];
|
34
128
|
report;
|
129
|
+
enabled = true;
|
130
|
+
nodeCounter = 0;
|
35
131
|
static async create(norsk, cfg, report) {
|
36
132
|
const node = new AutoCmaf(cfg, norsk, report);
|
37
133
|
await node.initialised;
|
@@ -83,25 +179,60 @@ class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
|
83
179
|
this.advertDestinations.push(id);
|
84
180
|
}
|
85
181
|
});
|
182
|
+
this.advertDestinations.push('local');
|
86
183
|
this.initialised = this.initialise();
|
87
184
|
}
|
88
185
|
async initialise() {
|
186
|
+
if (this.cfg.drmProvider) {
|
187
|
+
if (this.cfg.drmProvider === 'ezdrm') {
|
188
|
+
this.crypto = await (0, ezdrm_1.ezdrmInit)(this.cfg.__global?.ezdrmConfig);
|
189
|
+
}
|
190
|
+
if (this.cfg.drmProvider === 'axinom') {
|
191
|
+
this.crypto = await (0, axinom_1.axinomInit)(this.cfg.__global?.axinomConfig);
|
192
|
+
}
|
193
|
+
}
|
194
|
+
const mvCryptoSettings = this.crypto ? {
|
195
|
+
m3uAdditions: [
|
196
|
+
this.crypto.audio.multivariantSignaling,
|
197
|
+
this.crypto.video.multivariantSignaling,
|
198
|
+
].join("\n"),
|
199
|
+
mpdAdditions: "",
|
200
|
+
} : {};
|
89
201
|
const mv = await this.norsk.output.cmafMultiVariant({
|
90
|
-
id: `${this.cfg.id}-multivariant
|
202
|
+
id: this.incrementNodeId(`${this.cfg.id}-multivariant`),
|
91
203
|
playlistName: this.cfg.name,
|
92
|
-
destinations: this.destinations
|
204
|
+
destinations: this.destinations,
|
205
|
+
...mvCryptoSettings,
|
93
206
|
});
|
94
207
|
this.setup({ sink: mv });
|
95
208
|
this.mv = mv;
|
96
209
|
}
|
97
|
-
|
98
|
-
this.
|
99
|
-
|
100
|
-
|
210
|
+
incrementNodeId(id) {
|
211
|
+
this.nodeCounter++;
|
212
|
+
return `${id}-${this.nodeCounter}`;
|
213
|
+
}
|
214
|
+
async enableOutput() {
|
215
|
+
if (!this.enabled) {
|
216
|
+
this.enabled = true;
|
217
|
+
await this.handleContext();
|
218
|
+
(0, logging_1.debuglog)("Output enabled", { id: this.id });
|
101
219
|
}
|
102
|
-
return true;
|
103
220
|
}
|
104
|
-
async
|
221
|
+
async disableOutput() {
|
222
|
+
if (this.enabled) {
|
223
|
+
this.enabled = false;
|
224
|
+
for (const media of this.currentMedia) {
|
225
|
+
await media.node.close();
|
226
|
+
}
|
227
|
+
this.currentMedia = [];
|
228
|
+
(0, logging_1.debuglog)("output disabled", { id: this.id });
|
229
|
+
}
|
230
|
+
}
|
231
|
+
async handleContext() {
|
232
|
+
if (!this.enabled) {
|
233
|
+
(0, logging_1.debuglog)("Skipping context handling - output disabled", { id: this.id });
|
234
|
+
return;
|
235
|
+
}
|
105
236
|
const streams = [];
|
106
237
|
this.currentSources.forEach((subscription) => {
|
107
238
|
for (const stream of subscription.latestStreams()) {
|
@@ -117,13 +248,9 @@ class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
|
117
248
|
const existing = this.currentMedia.find((e) => (0, norsk_sdk_1.streamKeysAreEqual)(e.key, stream.key));
|
118
249
|
if (existing)
|
119
250
|
return;
|
120
|
-
|
121
|
-
key: stream.key,
|
122
|
-
node: undefined,
|
123
|
-
scheduleAd: (_ad, _destinationId) => { }
|
124
|
-
};
|
125
|
-
this.currentMedia.push(newMedia);
|
251
|
+
(0, logging_1.debuglog)("Handling new stream in AutoCMAF", { id: this.id, streamKey: stream.key });
|
126
252
|
if (this.currentMultiVariants.length == 0) {
|
253
|
+
(0, logging_1.debuglog)("Setting default multi-variant in AutoCMAF", { id: this.id, streamKey: stream.key });
|
127
254
|
this.defaultProgramNumber = stream.key.programNumber;
|
128
255
|
this.defaultSourceName = stream.key.sourceName;
|
129
256
|
}
|
@@ -135,10 +262,11 @@ class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
|
135
262
|
};
|
136
263
|
this.currentMultiVariants.push(newMv);
|
137
264
|
const mv = await this.norsk.output.cmafMultiVariant({
|
138
|
-
id: `${this.cfg.id}-multivariant-${stream.key.sourceName}-${stream.key.programNumber}
|
265
|
+
id: this.incrementNodeId(`${this.cfg.id}-multivariant-${stream.key.sourceName}-${stream.key.programNumber}`),
|
139
266
|
playlistName: `${this.cfg.name}-${stream.key.sourceName}-${stream.key.programNumber}`,
|
140
267
|
destinations: this.destinations
|
141
268
|
});
|
269
|
+
(0, logging_1.debuglog)("Creating program-specific multi-variant in AutoCMAF", { id: this.id, streamKey: stream.key });
|
142
270
|
newMv.node = mv;
|
143
271
|
this.report.registerOutput(this.cfg.id, mv.url);
|
144
272
|
}
|
@@ -147,44 +275,68 @@ class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
|
147
275
|
case undefined:
|
148
276
|
throw "Bad server message";
|
149
277
|
case "video": {
|
278
|
+
const videoCryptoSettings = this.crypto ? {
|
279
|
+
encryption: this.crypto.video,
|
280
|
+
m3uAdditions: this.crypto.video.mediaSignaling,
|
281
|
+
mpdAdditions: this.crypto.video.dashSignalling,
|
282
|
+
} : {};
|
150
283
|
const video = await this.norsk.output.cmafVideo({
|
151
284
|
segmentDurationSeconds: this.cfg.segments.targetSegmentDuration,
|
152
285
|
partDurationSeconds: this.cfg.segments.targetPartDuration,
|
153
286
|
destinations: this.destinations,
|
154
|
-
id: `${this.id}-${streamKeyString}-video`
|
287
|
+
id: this.incrementNodeId(`${this.id}-${streamKeyString}-video`),
|
288
|
+
...videoCryptoSettings,
|
155
289
|
});
|
156
|
-
|
157
|
-
|
158
|
-
const now = new Date();
|
159
|
-
video.scheduleTag(ad, now, destinationId);
|
160
|
-
};
|
290
|
+
video.onPlaylistAddition = (_, p) => p;
|
291
|
+
video.onPlaylistAddition = undefined;
|
161
292
|
subscribes.push(new Promise((resolve, _reject) => {
|
162
293
|
video.subscribe([{
|
163
294
|
source: stream.source,
|
164
295
|
sourceSelector: (0, norsk_sdk_1.selectExactKey)(stream.key)
|
165
296
|
}], (_) => true, (_) => resolve({}));
|
166
297
|
}));
|
298
|
+
const newMedia = {
|
299
|
+
key: stream.key,
|
300
|
+
node: video,
|
301
|
+
scheduleAd: (ad, destinationId) => {
|
302
|
+
const now = new Date();
|
303
|
+
video.scheduleTag(ad, now, destinationId);
|
304
|
+
}
|
305
|
+
};
|
306
|
+
this.currentMedia.push(newMedia);
|
167
307
|
this.registerInput(video);
|
168
308
|
break;
|
169
309
|
}
|
170
310
|
case "audio": {
|
311
|
+
const audioCryptoSettings = this.crypto ? {
|
312
|
+
encryption: this.crypto.audio,
|
313
|
+
m3uAdditions: this.crypto.audio.mediaSignaling,
|
314
|
+
mpdAdditions: this.crypto.audio.dashSignalling,
|
315
|
+
} : {};
|
171
316
|
const audio = await this.norsk.output.cmafAudio({
|
172
317
|
segmentDurationSeconds: this.cfg.segments.targetSegmentDuration,
|
173
318
|
partDurationSeconds: this.cfg.segments.targetPartDuration,
|
174
319
|
destinations: this.destinations,
|
175
|
-
id: `${this.id}-${streamKeyString}-
|
320
|
+
id: this.incrementNodeId(`${this.id}-${streamKeyString}-video`),
|
321
|
+
...audioCryptoSettings,
|
176
322
|
});
|
177
|
-
|
178
|
-
|
179
|
-
const now = new Date();
|
180
|
-
audio.scheduleTag(ad, now, destinationId);
|
181
|
-
};
|
323
|
+
audio.onPlaylistAddition = (_, p) => p;
|
324
|
+
audio.onPlaylistAddition = undefined;
|
182
325
|
subscribes.push(new Promise((resolve, _reject) => {
|
183
326
|
audio.subscribe([{
|
184
327
|
source: stream.source,
|
185
328
|
sourceSelector: (0, norsk_sdk_1.selectExactKey)(stream.key)
|
186
329
|
}], (_) => true, (_) => resolve({}));
|
187
330
|
}));
|
331
|
+
const newMedia = {
|
332
|
+
key: stream.key,
|
333
|
+
node: audio,
|
334
|
+
scheduleAd: (ad, destinationId) => {
|
335
|
+
const now = new Date();
|
336
|
+
audio.scheduleTag(ad, now, destinationId);
|
337
|
+
}
|
338
|
+
};
|
339
|
+
this.currentMedia.push(newMedia);
|
188
340
|
this.registerInput(audio);
|
189
341
|
break;
|
190
342
|
}
|
@@ -192,17 +344,21 @@ class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
|
192
344
|
const subtitle = await this.norsk.output.cmafWebVtt({
|
193
345
|
segmentDurationSeconds: this.cfg.segments.targetSegmentDuration,
|
194
346
|
destinations: this.destinations,
|
195
|
-
id: `${this.id}-${streamKeyString}-webvtt`
|
347
|
+
id: this.incrementNodeId(`${this.id}-${streamKeyString}-webvtt`),
|
196
348
|
});
|
197
|
-
newMedia.node = subtitle;
|
198
|
-
newMedia.scheduleAd = (ad, destinationId) => {
|
199
|
-
const now = new Date();
|
200
|
-
subtitle.scheduleTag(ad, now, destinationId);
|
201
|
-
};
|
202
349
|
subtitle.subscribe([{
|
203
350
|
source: stream.source,
|
204
351
|
sourceSelector: (0, norsk_sdk_1.selectExactKey)(stream.key)
|
205
352
|
}]);
|
353
|
+
const newMedia = {
|
354
|
+
key: stream.key,
|
355
|
+
node: subtitle,
|
356
|
+
scheduleAd: (ad, destinationId) => {
|
357
|
+
const now = new Date();
|
358
|
+
subtitle.scheduleTag(ad, now, destinationId);
|
359
|
+
}
|
360
|
+
};
|
361
|
+
this.currentMedia.push(newMedia);
|
206
362
|
this.registerInput(subtitle);
|
207
363
|
break;
|
208
364
|
}
|
@@ -223,7 +379,7 @@ class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
|
223
379
|
id: adId,
|
224
380
|
scte35: message,
|
225
381
|
startDate: schedule,
|
226
|
-
durationSeconds: Number(command.breakDuration
|
382
|
+
durationSeconds: Number((command.breakDuration?.duration ?? 0n) / BigInt(90000.0))
|
227
383
|
}, d);
|
228
384
|
}
|
229
385
|
}
|
@@ -249,14 +405,9 @@ class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
|
249
405
|
return true;
|
250
406
|
});
|
251
407
|
for (const deletion of deletions) {
|
252
|
-
const node = deletion
|
253
|
-
deletion.node = undefined;
|
254
|
-
await node?.close();
|
408
|
+
const node = deletion.node;
|
255
409
|
this.currentMedia = this.currentMedia.filter((x) => !(0, norsk_sdk_1.streamKeysAreEqual)(x.key, deletion.key));
|
256
|
-
|
257
|
-
const thisResponse = this.pendingResponses.shift();
|
258
|
-
if (this.pendingResponses.length > 0) {
|
259
|
-
await this.popContextStack();
|
410
|
+
await node.close();
|
260
411
|
}
|
261
412
|
await Promise.all(creations);
|
262
413
|
const defaultSources = this.currentMedia.flatMap((m) => {
|
@@ -284,26 +435,13 @@ class AutoCmaf extends base_nodes_1.CustomSinkNode {
|
|
284
435
|
mv.node?.subscribe(sources);
|
285
436
|
}
|
286
437
|
await Promise.all(subscribes);
|
287
|
-
if (thisResponse)
|
288
|
-
thisResponse();
|
289
438
|
}
|
290
439
|
subscribe(subs) {
|
291
|
-
|
292
|
-
subs.forEach((
|
293
|
-
|
294
|
-
}, new Map());
|
295
|
-
this.currentSources.forEach((subscription, source) => {
|
296
|
-
if (!newSources.has(source)) {
|
297
|
-
subscription.unregisterForContextChange(this);
|
298
|
-
}
|
299
|
-
});
|
300
|
-
newSources.forEach((subscription, source) => {
|
301
|
-
if (!this.currentSources.has(source)) {
|
302
|
-
subscription.registerForContextChange(this);
|
303
|
-
}
|
440
|
+
this.currentSources = new Map();
|
441
|
+
subs.forEach((s) => {
|
442
|
+
this.currentSources.set(s.source, s);
|
304
443
|
});
|
305
|
-
this.
|
306
|
-
void this.sourceContextChange((() => { }));
|
444
|
+
this.control.setSources(subs);
|
307
445
|
}
|
308
446
|
}
|
309
447
|
exports.AutoCmaf = AutoCmaf;
|