@norskvideo/norsk-studio-alpha 1.27.0-2025-07-09-0fcad3ea
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 +10 -0
- package/client/info.js +43461 -0
- package/client/processor.audioLevel/styles.css +165 -0
- package/client/shared/style.css +1627 -0
- package/client/shared/tailwind.css +31 -0
- package/client/style.css +1074 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +14 -0
- package/lib/index.js.map +1 -0
- package/lib/info.d.ts +3 -0
- package/lib/info.js +44 -0
- package/lib/info.js.map +1 -0
- package/lib/input.decklink/info.d.ts +3 -0
- package/lib/input.decklink/info.js +51 -0
- package/lib/input.decklink/info.js.map +1 -0
- package/lib/input.decklink/runtime.d.ts +12 -0
- package/lib/input.decklink/runtime.js +22 -0
- package/lib/input.decklink/runtime.js.map +1 -0
- package/lib/input.decklink/types.d.ts +23 -0
- package/lib/input.decklink/types.js +3 -0
- package/lib/input.decklink/types.js.map +1 -0
- package/lib/input.decklink/types.yaml +32 -0
- package/lib/input.mp4file/info.d.ts +3 -0
- package/lib/input.mp4file/info.js +34 -0
- package/lib/input.mp4file/info.js.map +1 -0
- package/lib/input.mp4file/runtime.d.ts +14 -0
- package/lib/input.mp4file/runtime.js +33 -0
- package/lib/input.mp4file/runtime.js.map +1 -0
- package/lib/input.mp4file/types.d.ts +23 -0
- package/lib/input.mp4file/types.js +3 -0
- package/lib/input.mp4file/types.js.map +1 -0
- package/lib/input.mp4file/types.yaml +30 -0
- package/lib/input.ndi/info.d.ts +3 -0
- package/lib/input.ndi/info.js +52 -0
- package/lib/input.ndi/info.js.map +1 -0
- package/lib/input.ndi/runtime.d.ts +24 -0
- package/lib/input.ndi/runtime.js +60 -0
- package/lib/input.ndi/runtime.js.map +1 -0
- package/lib/input.ndi/source-selection.d.ts +10 -0
- package/lib/input.ndi/source-selection.js +84 -0
- package/lib/input.ndi/source-selection.js.map +1 -0
- package/lib/input.ndi/types.d.ts +52 -0
- package/lib/input.ndi/types.js +3 -0
- package/lib/input.ndi/types.js.map +1 -0
- package/lib/input.ndi/types.yaml +37 -0
- package/lib/output.ndi/info.d.ts +8 -0
- package/lib/output.ndi/info.js +61 -0
- package/lib/output.ndi/info.js.map +1 -0
- package/lib/output.ndi/inline-view.d.ts +6 -0
- package/lib/output.ndi/inline-view.js +12 -0
- package/lib/output.ndi/inline-view.js.map +1 -0
- package/lib/output.ndi/runtime.d.ts +14 -0
- package/lib/output.ndi/runtime.js +35 -0
- package/lib/output.ndi/runtime.js.map +1 -0
- package/lib/output.ndi/types.d.ts +35 -0
- package/lib/output.ndi/types.js +3 -0
- package/lib/output.ndi/types.js.map +1 -0
- package/lib/output.ndi/types.yaml +72 -0
- package/lib/output.recorder/info.d.ts +10 -0
- package/lib/output.recorder/info.js +79 -0
- package/lib/output.recorder/info.js.map +1 -0
- package/lib/output.recorder/runtime.d.ts +66 -0
- package/lib/output.recorder/runtime.js +301 -0
- package/lib/output.recorder/runtime.js.map +1 -0
- package/lib/output.recorder/types.d.ts +225 -0
- package/lib/output.recorder/types.js +3 -0
- package/lib/output.recorder/types.js.map +1 -0
- package/lib/output.recorder/types.yaml +211 -0
- package/lib/processor.actionReplay/info.d.ts +25 -0
- package/lib/processor.actionReplay/info.js +77 -0
- package/lib/processor.actionReplay/info.js.map +1 -0
- package/lib/processor.actionReplay/runtime.d.ts +38 -0
- package/lib/processor.actionReplay/runtime.js +225 -0
- package/lib/processor.actionReplay/runtime.js.map +1 -0
- package/lib/processor.actionReplay/summary.d.ts +4 -0
- package/lib/processor.actionReplay/summary.js +76 -0
- package/lib/processor.actionReplay/summary.js.map +1 -0
- package/lib/processor.actionReplay/types.d.ts +38 -0
- package/lib/processor.actionReplay/types.js +3 -0
- package/lib/processor.actionReplay/types.js.map +1 -0
- package/lib/processor.actionReplay/types.yaml +74 -0
- package/lib/processor.audioLevel/info.d.ts +27 -0
- package/lib/processor.audioLevel/info.js +61 -0
- package/lib/processor.audioLevel/info.js.map +1 -0
- package/lib/processor.audioLevel/inline-view.d.ts +4 -0
- package/lib/processor.audioLevel/inline-view.js +26 -0
- package/lib/processor.audioLevel/inline-view.js.map +1 -0
- package/lib/processor.audioLevel/runtime.d.ts +26 -0
- package/lib/processor.audioLevel/runtime.js +86 -0
- package/lib/processor.audioLevel/runtime.js.map +1 -0
- package/lib/processor.audioLevel/summary-view.d.ts +7 -0
- package/lib/processor.audioLevel/summary-view.js +37 -0
- package/lib/processor.audioLevel/summary-view.js.map +1 -0
- package/lib/processor.audioLevel/types.d.ts +42 -0
- package/lib/processor.audioLevel/types.js +3 -0
- package/lib/processor.audioLevel/types.js.map +1 -0
- package/lib/processor.audioLevel/types.yaml +83 -0
- package/lib/processor.gemini-poc/info.d.ts +8 -0
- package/lib/processor.gemini-poc/info.js +59 -0
- package/lib/processor.gemini-poc/info.js.map +1 -0
- package/lib/processor.gemini-poc/runtime.d.ts +38 -0
- package/lib/processor.gemini-poc/runtime.js +132 -0
- package/lib/processor.gemini-poc/runtime.js.map +1 -0
- package/lib/processor.gemini-poc/types.d.ts +23 -0
- package/lib/processor.gemini-poc/types.js +3 -0
- package/lib/processor.gemini-poc/types.js.map +1 -0
- package/lib/processor.gemini-poc/types.yaml +43 -0
- package/lib/processor.mixMinus/info.d.ts +7 -0
- package/lib/processor.mixMinus/info.js +40 -0
- package/lib/processor.mixMinus/info.js.map +1 -0
- package/lib/processor.mixMinus/runtime.d.ts +23 -0
- package/lib/processor.mixMinus/runtime.js +85 -0
- package/lib/processor.mixMinus/runtime.js.map +1 -0
- package/lib/processor.mixMinus/types.d.ts +18 -0
- package/lib/processor.mixMinus/types.js +3 -0
- package/lib/processor.mixMinus/types.js.map +1 -0
- package/lib/processor.mixMinus/types.yaml +19 -0
- package/lib/processor.monetise/info.d.ts +3 -0
- package/lib/processor.monetise/info.js +72 -0
- package/lib/processor.monetise/info.js.map +1 -0
- package/lib/processor.monetise/runtime.d.ts +62 -0
- package/lib/processor.monetise/runtime.js +217 -0
- package/lib/processor.monetise/runtime.js.map +1 -0
- package/lib/processor.monetise/summary.d.ts +7 -0
- package/lib/processor.monetise/summary.js +40 -0
- package/lib/processor.monetise/summary.js.map +1 -0
- package/lib/processor.monetise/types.d.ts +16 -0
- package/lib/processor.monetise/types.js +3 -0
- package/lib/processor.monetise/types.js.map +1 -0
- package/lib/processor.monetise/types.yaml +9 -0
- package/lib/processor.whisper-transcribe/info.d.ts +9 -0
- package/lib/processor.whisper-transcribe/info.js +46 -0
- package/lib/processor.whisper-transcribe/info.js.map +1 -0
- package/lib/processor.whisper-transcribe/runtime.d.ts +22 -0
- package/lib/processor.whisper-transcribe/runtime.js +70 -0
- package/lib/processor.whisper-transcribe/runtime.js.map +1 -0
- package/lib/processor.whisper-transcribe/types.d.ts +21 -0
- package/lib/processor.whisper-transcribe/types.js +3 -0
- package/lib/processor.whisper-transcribe/types.js.map +1 -0
- package/lib/processor.whisper-transcribe/types.yaml +28 -0
- package/lib/shared/schemas.d.ts +8 -0
- package/lib/shared/schemas.js +44 -0
- package/lib/shared/schemas.js.map +1 -0
- package/lib/test/output.recorder.d.ts +1 -0
- package/lib/test/output.recorder.js +186 -0
- package/lib/test/output.recorder.js.map +1 -0
- package/lib/util.timestamps/info.d.ts +14 -0
- package/lib/util.timestamps/info.js +64 -0
- package/lib/util.timestamps/info.js.map +1 -0
- package/lib/util.timestamps/inline-view.d.ts +6 -0
- package/lib/util.timestamps/inline-view.js +95 -0
- package/lib/util.timestamps/inline-view.js.map +1 -0
- package/lib/util.timestamps/runtime.d.ts +13 -0
- package/lib/util.timestamps/runtime.js +51 -0
- package/lib/util.timestamps/runtime.js.map +1 -0
- package/lib/util.timestamps/types.d.ts +36 -0
- package/lib/util.timestamps/types.js +3 -0
- package/lib/util.timestamps/types.js.map +1 -0
- package/lib/util.timestamps/types.yaml +74 -0
- package/package.json +57 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
27
|
+
};
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
29
|
+
exports.waitForAssert = waitForAssert;
|
30
|
+
const norsk_sdk_1 = require("@norskvideo/norsk-sdk");
|
31
|
+
const __1 = require("../");
|
32
|
+
const builder_1 = require("@norskvideo/norsk-studio/lib/test/_util/builder");
|
33
|
+
const document = __importStar(require("@norskvideo/norsk-studio/lib/runtime/document"));
|
34
|
+
const yaml_1 = __importDefault(require("yaml"));
|
35
|
+
const execution_1 = __importStar(require("@norskvideo/norsk-studio/lib/runtime/execution"));
|
36
|
+
const express_1 = __importDefault(require("express"));
|
37
|
+
const client_types_1 = require("@norskvideo/norsk-studio/lib/extension/client-types");
|
38
|
+
const sources_1 = require("@norskvideo/norsk-studio/lib/test/_util/sources");
|
39
|
+
const info_1 = __importDefault(require("../output.recorder/info"));
|
40
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
41
|
+
const chai_1 = require("chai");
|
42
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
43
|
+
const util_1 = require("@norskvideo/norsk-studio/lib/shared/util");
|
44
|
+
async function defaultRuntime() {
|
45
|
+
const runtime = (0, builder_1.emptyRuntime)();
|
46
|
+
await (0, __1.registerAll)(runtime);
|
47
|
+
return runtime;
|
48
|
+
}
|
49
|
+
describe("Output Recorder", () => {
|
50
|
+
async function testDocument() {
|
51
|
+
const runtime = await defaultRuntime();
|
52
|
+
await promises_1.default.rm('/tmp/recorder', { recursive: true, force: true });
|
53
|
+
const yaml = new builder_1.YamlBuilder()
|
54
|
+
.addNode(new builder_1.YamlNodeBuilder('recorder', (0, info_1.default)(client_types_1.RegistrationConsts), {
|
55
|
+
store_path: '/tmp/recorder',
|
56
|
+
cuts_path: '/tmp/recorder',
|
57
|
+
expiry_hours: 1
|
58
|
+
}).reify())
|
59
|
+
.reify();
|
60
|
+
const compiled = document.load(__filename, runtime, yaml_1.default.stringify(yaml));
|
61
|
+
return compiled;
|
62
|
+
}
|
63
|
+
let norsk = undefined;
|
64
|
+
let app;
|
65
|
+
let server;
|
66
|
+
let port;
|
67
|
+
let result;
|
68
|
+
let recorder;
|
69
|
+
function latest() {
|
70
|
+
return result.runtimeState.latest['recorder'];
|
71
|
+
}
|
72
|
+
after(async () => {
|
73
|
+
clearInterval(recorder?.timer);
|
74
|
+
await norsk?.close();
|
75
|
+
server?.close();
|
76
|
+
});
|
77
|
+
before(async () => {
|
78
|
+
const compiled = await testDocument();
|
79
|
+
norsk = await norsk_sdk_1.Norsk.connect({ onShutdown: () => { } });
|
80
|
+
const source = await (0, sources_1.videoAndAudio)(norsk, 'source');
|
81
|
+
app = (0, express_1.default)();
|
82
|
+
app.use(express_1.default.json());
|
83
|
+
server = app.listen(0);
|
84
|
+
port = server.address().port;
|
85
|
+
result = await (0, execution_1.default)(norsk, compiled, app);
|
86
|
+
recorder = result.components["recorder"];
|
87
|
+
const sink = new execution_1.ComponentSubscriptions(norsk, recorder);
|
88
|
+
sink.setSources([new execution_1.StudioNodeSubscriptionSource(source, (0, sources_1.testSourceDescription)(), {
|
89
|
+
type: "take-all-streams", filter: client_types_1.Av.map((media) => ({ media }))
|
90
|
+
})]);
|
91
|
+
return new Promise((r) => {
|
92
|
+
setTimeout(r, 10000.0);
|
93
|
+
});
|
94
|
+
});
|
95
|
+
describe("timeline", () => {
|
96
|
+
it("has a single entry with some data", async () => {
|
97
|
+
const request = await (0, node_fetch_1.default)(`http://localhost:${port}/recorder/timeline`);
|
98
|
+
const body = await request.json();
|
99
|
+
(0, chai_1.expect)(body.timeline.length).equal(1);
|
100
|
+
});
|
101
|
+
});
|
102
|
+
describe("creating a cut", () => {
|
103
|
+
let cutUrl;
|
104
|
+
before(async () => {
|
105
|
+
const { timeline } = (await (0, node_fetch_1.default)(`http://localhost:${port}/recorder/timeline`).then(async (r) => r.json()));
|
106
|
+
const request = await (0, node_fetch_1.default)(`http://localhost:${port}/recorder/cut`, {
|
107
|
+
method: 'POST',
|
108
|
+
headers: { 'content-type': 'application/json', 'accept': 'application/json' },
|
109
|
+
body: JSON.stringify({
|
110
|
+
start: timeline[0].start,
|
111
|
+
duration_s: 5.0
|
112
|
+
})
|
113
|
+
});
|
114
|
+
(0, chai_1.expect)(request.status).equal(201);
|
115
|
+
const { url } = (await request.json());
|
116
|
+
cutUrl = url;
|
117
|
+
});
|
118
|
+
it("returns the URL to the cut", async () => {
|
119
|
+
(0, chai_1.expect)(cutUrl).not.empty;
|
120
|
+
});
|
121
|
+
it("the url contains the current status", async () => {
|
122
|
+
const status = await (0, node_fetch_1.default)(`http://localhost:${port}/recorder/${cutUrl}`).then(async (r) => r.json());
|
123
|
+
(0, chai_1.expect)(status.status).not.empty;
|
124
|
+
});
|
125
|
+
it("adds a cut to the collection", async () => {
|
126
|
+
(0, chai_1.expect)(latest().cuts.length).equal(1);
|
127
|
+
});
|
128
|
+
it("updates percentage complete", async () => {
|
129
|
+
await waitForAssert(async () => latest().cuts[0].percent == 100.0, async () => {
|
130
|
+
const status = await (0, node_fetch_1.default)(`http://localhost:${port}/recorder/${cutUrl}`).then(async (r) => r.json());
|
131
|
+
(0, chai_1.expect)(latest().cuts[0].percent).equal(100.0);
|
132
|
+
(0, chai_1.expect)(status.status).equal('CutReady');
|
133
|
+
});
|
134
|
+
});
|
135
|
+
it("provides the file over the API", async () => {
|
136
|
+
await (0, util_1.waitForCondition)(() => latest().cuts[0].percent == 100.0);
|
137
|
+
const status = await (0, node_fetch_1.default)(`http://localhost:${port}/recorder/${cutUrl}`).then(async (r) => r.json());
|
138
|
+
if (status.status !== 'CutReady')
|
139
|
+
throw "Cut not ready";
|
140
|
+
const request = await (0, node_fetch_1.default)(`http://localhost:${port}/recorder/${status.url}`);
|
141
|
+
(0, chai_1.expect)(request.status).equal(200);
|
142
|
+
const buffer = await request.text();
|
143
|
+
(0, chai_1.expect)(buffer.length).greaterThan(0);
|
144
|
+
});
|
145
|
+
it("Prunes the file and makes it unavailable", async () => {
|
146
|
+
await (0, util_1.waitForCondition)(() => latest().cuts[0].percent == 100.0);
|
147
|
+
recorder.cfg.expiry_hours = 0.0;
|
148
|
+
await recorder.pruneCutStore();
|
149
|
+
const status = await (0, node_fetch_1.default)(`http://localhost:${port}/recorder/${cutUrl}`).then(async (r) => r.json());
|
150
|
+
if (status.status !== 'CutReady')
|
151
|
+
throw new Error("Cut not ready");
|
152
|
+
const request = await (0, node_fetch_1.default)(`http://localhost:${port}/recorder/${status.url}`);
|
153
|
+
const _buffer = await request.text();
|
154
|
+
(0, chai_1.expect)(request.status).equal(404);
|
155
|
+
});
|
156
|
+
});
|
157
|
+
describe("invalid requests", () => {
|
158
|
+
});
|
159
|
+
});
|
160
|
+
async function waitForAssert(condition, assert, timeout, interval) {
|
161
|
+
return new Promise((resolve, reject) => {
|
162
|
+
const doAssert = () => {
|
163
|
+
try {
|
164
|
+
void assert().then(resolve);
|
165
|
+
}
|
166
|
+
catch (e) {
|
167
|
+
reject(e);
|
168
|
+
}
|
169
|
+
};
|
170
|
+
const failure = setTimeout(() => {
|
171
|
+
clearTimeout(failure);
|
172
|
+
clearInterval(check);
|
173
|
+
doAssert();
|
174
|
+
}, timeout);
|
175
|
+
const check = setInterval(() => {
|
176
|
+
void condition().then((result) => {
|
177
|
+
if (result) {
|
178
|
+
clearTimeout(failure);
|
179
|
+
clearInterval(check);
|
180
|
+
doAssert();
|
181
|
+
}
|
182
|
+
});
|
183
|
+
}, interval);
|
184
|
+
});
|
185
|
+
}
|
186
|
+
//# sourceMappingURL=output.recorder.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"output.recorder.js","sourceRoot":"","sources":["../../src/test/output.recorder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyLA,sCA6BC;AAtND,qDAA8C;AAC9C,2BAAkC;AAElC,6EAA4G;AAC5G,wFAA0E;AAC1E,gDAAwB;AACxB,4FAAqI;AACrI,sDAA8B;AAI9B,sFAA6F;AAC7F,6EAAuH;AAEvH,mEAAmD;AACnD,4DAA+B;AAC/B,+BAA8B;AAC9B,2DAA6B;AAC7B,mEAA4E;AAE5E,KAAK,UAAU,cAAc;IAC3B,MAAM,OAAO,GAAG,IAAA,sBAAY,GAAE,CAAC;IAC/B,MAAM,IAAA,eAAW,EAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,KAAK,UAAU,YAAY;QACzB,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC;QACvC,MAAM,kBAAE,CAAC,EAAE,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAG,IAAI,qBAAW,EAAE;aAC3B,OAAO,CACN,IAAI,yBAAe,CAChB,UAAU,EACT,IAAA,cAAY,EAAC,iCAAkB,CAAC,EAChC;YACE,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,eAAe;YAC1B,YAAY,EAAE,CAAC;SAChB,CACF,CAAC,KAAK,EAAE,CAAC;aACb,KAAK,EAAE,CAAC;QAGX,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,cAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1E,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,GAAsB,SAAS,CAAC;IACzC,IAAI,GAAwB,CAAC;IAC7B,IAAI,MAAc,CAAC;IACnB,IAAI,IAAY,CAAC;IACjB,IAAI,MAAiB,CAAC;IACtB,IAAI,QAAkB,CAAC;IAGvB,SAAS,MAAM;QACb,OAAO,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAkB,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC/B,MAAM,KAAK,EAAE,KAAK,EAAE,CAAC;QACrB,MAAM,EAAE,KAAK,EAAE,CAAC;IAClB,CAAC,CAAC,CAAA;IAIF,MAAM,CAAC,KAAK,IAAI,EAAE;QAChB,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;QACtC,KAAK,GAAG,MAAM,iBAAK,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAa,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACpD,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;QAChB,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,GAAI,MAAM,CAAC,OAAO,EAAkB,CAAC,IAAI,CAAC;QAC9C,MAAM,GAAG,MAAM,IAAA,mBAAE,EAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;QAExC,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAa,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,kCAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACzD,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,wCAA4B,CAC/C,MAAM,EACN,IAAA,+BAAqB,GAAE,EACvB;gBACE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,iBAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;aACjE,CAAC,CAAC,CAAC,CAAA;QAGN,OAAO,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE;YAC7B,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;QACxB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACjD,MAAM,OAAO,GAAG,MAAM,IAAA,oBAAK,EAAC,oBAAoB,IAAI,oBAAoB,CAAC,CAAC;YAC1E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAmC,CAAC;YACnE,IAAA,aAAM,EAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,IAAI,MAAc,CAAC;QACnB,MAAM,CAAC,KAAK,IAAI,EAAE;YAChB,MAAM,EAAE,QAAQ,EAAE,GAAkC,CAAC,MAAM,IAAA,oBAAK,EAAC,oBAAoB,IAAI,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAkC,CAAC;YAC7K,MAAM,OAAO,GAAG,MAAM,IAAA,oBAAK,EAAC,oBAAoB,IAAI,eAAe,EAAE;gBACnE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,kBAAkB,EAAE;gBAC7E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK;oBACxB,UAAU,EAAE,GAAG;iBAChB,CAAC;aACH,CAAC,CAAC;YACH,IAAA,aAAM,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAoB,CAAA;YACzD,MAAM,GAAG,GAAG,CAAC;QACf,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAE1C,IAAA,aAAM,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAC3B,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,MAAM,GAAc,MAAM,IAAA,oBAAK,EAAC,oBAAoB,IAAI,aAAa,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAc,CAAA;YAE7H,IAAA,aAAM,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QAClC,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC5C,IAAA,aAAM,EAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,aAAa,CACjB,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,KAAK,EAC7C,KAAK,IAAI,EAAE;gBACT,MAAM,MAAM,GAAc,MAAM,IAAA,oBAAK,EAAC,oBAAoB,IAAI,aAAa,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAc,CAAA;gBAC7H,IAAA,aAAM,EAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;gBAC7C,IAAA,aAAM,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC1C,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,IAAA,uBAAgB,EACpB,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,KAAK,CACxC,CAAA;YACD,MAAM,MAAM,GAAc,MAAM,IAAA,oBAAK,EAAC,oBAAoB,IAAI,aAAa,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAc,CAAA;YAC7H,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;gBAAE,MAAM,eAAe,CAAC;YAExD,MAAM,OAAO,GAAG,MAAM,IAAA,oBAAK,EAAC,oBAAoB,IAAI,aAAa,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/E,IAAA,aAAM,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YAEpC,IAAA,aAAM,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAEvC,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,IAAA,uBAAgB,EACpB,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,KAAK,CACxC,CAAA;YAED,QAAQ,CAAC,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC;YAChC,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAC;YAG/B,MAAM,MAAM,GAAc,MAAM,IAAA,oBAAK,EAAC,oBAAoB,IAAI,aAAa,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAc,CAAA;YAC7H,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;YAEnE,MAAM,OAAO,GAAG,MAAM,IAAA,oBAAK,EAAC,oBAAoB,IAAI,aAAa,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/E,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACrC,IAAA,aAAM,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAIlC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAGK,KAAK,UAAU,aAAa,CACjC,SAAmC,EACnC,MAA6B,EAC7B,OAAgB,EAChB,QAAiB;IACjB,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,IAAI,CAAC;gBACH,KAAK,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC7B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,CAAC,CAAC,CAAC;YACZ,CAAC;QACH,CAAC,CAAA;QACD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,QAAQ,EAAE,CAAC;QACb,CAAC,EAAE,OAAO,CAAC,CAAA;QAEX,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,KAAK,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC/B,IAAI,MAAM,EAAE,CAAC;oBACX,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,aAAa,CAAC,KAAK,CAAC,CAAC;oBACrB,QAAQ,EAAE,CAAC;gBACb,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,QAAQ,CAAC,CAAA;IACd,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import type Registration from "@norskvideo/norsk-studio/lib/extension/registration";
|
2
|
+
export default function (R: Registration): import("@norskvideo/norsk-studio/lib/extension/client-types").NodeInfo<{
|
3
|
+
id: string;
|
4
|
+
displayName: string;
|
5
|
+
}, {
|
6
|
+
timestamps: import("./types").components["schemas"]["TimestampCollection"][];
|
7
|
+
}, Record<string, never>, {
|
8
|
+
type: "new-timestamp";
|
9
|
+
key: string;
|
10
|
+
value: number;
|
11
|
+
wallMs: number;
|
12
|
+
}>;
|
13
|
+
export declare const hardwareNames: readonly ["quadra", "nvidia"];
|
14
|
+
export type HardwareName = typeof hardwareNames[number];
|
@@ -0,0 +1,64 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.hardwareNames = void 0;
|
7
|
+
exports.default = default_1;
|
8
|
+
const inline_view_1 = __importDefault(require("./inline-view"));
|
9
|
+
function default_1(R) {
|
10
|
+
const { defineComponent, All } = R;
|
11
|
+
return defineComponent({
|
12
|
+
identifier: 'util.timestamps',
|
13
|
+
category: 'output',
|
14
|
+
name: "Jitter",
|
15
|
+
description: "A jitter utility which processes and tracks timestamps.",
|
16
|
+
subscription: {
|
17
|
+
accepts: {
|
18
|
+
type: "dynamic-streams",
|
19
|
+
mode: 'any',
|
20
|
+
streams: () => All.map((media) => ({ media }))
|
21
|
+
},
|
22
|
+
produces: undefined
|
23
|
+
},
|
24
|
+
display: (_desc) => { return {}; },
|
25
|
+
runtime: {
|
26
|
+
initialState: () => ({
|
27
|
+
timestamps: [],
|
28
|
+
}),
|
29
|
+
handleEvent(ev, state) {
|
30
|
+
const evType = ev.type;
|
31
|
+
switch (evType) {
|
32
|
+
case "new-timestamp": {
|
33
|
+
const target = state.timestamps.find((e) => e.key === ev.key) ??
|
34
|
+
(() => {
|
35
|
+
const start = { key: ev.key, startTimeMs: new Date().valueOf(), startTimestamp: ev.value, timestamps: [] };
|
36
|
+
state.timestamps.push(start);
|
37
|
+
return start;
|
38
|
+
})();
|
39
|
+
target.timestamps.push({ ts: ev.value, wall: ev.wallMs });
|
40
|
+
while (target.timestamps.length > 200) {
|
41
|
+
target.timestamps.splice(0, 1);
|
42
|
+
}
|
43
|
+
break;
|
44
|
+
}
|
45
|
+
default:
|
46
|
+
assertUnreachable(evType);
|
47
|
+
}
|
48
|
+
return { ...state };
|
49
|
+
},
|
50
|
+
inline: inline_view_1.default
|
51
|
+
},
|
52
|
+
configForm: {
|
53
|
+
form: {}
|
54
|
+
}
|
55
|
+
});
|
56
|
+
}
|
57
|
+
function assertUnreachable(_) {
|
58
|
+
throw new Error("Didn't expect to get here");
|
59
|
+
}
|
60
|
+
exports.hardwareNames = [
|
61
|
+
'quadra',
|
62
|
+
'nvidia'
|
63
|
+
];
|
64
|
+
//# sourceMappingURL=info.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"info.js","sourceRoot":"","sources":["../../src/util.timestamps/info.ts"],"names":[],"mappings":";;;;;;AAIA,4BAoDC;AAtDD,gEAAuC;AAEvC,mBAAwB,CAAe;IACrC,MAAM,EACJ,eAAe,EACf,GAAG,EACJ,GAAG,CAAC,CAAC;IAEN,OAAO,eAAe,CAA8F;QAClH,UAAU,EAAE,iBAAiB;QAC7B,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,yDAAyD;QACtE,YAAY,EAAE;YACZ,OAAO,EAAE;gBACP,IAAI,EAAE,iBAAiB;gBACvB,IAAI,EAAE,KAAK;gBACX,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;aAC/C;YACD,QAAQ,EAAE,SAAS;SACpB;QACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC;QAClC,OAAO,EAAE;YACP,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;gBACnB,UAAU,EAAE,EAAE;aACf,CAAC;YACF,WAAW,CAAC,EAAE,EAAE,KAAK;gBACnB,MAAM,MAAM,GAAG,EAAE,CAAC,IAAI,CAAC;gBACvB,QAAQ,MAAM,EAAE,CAAC;oBACf,KAAK,eAAe,CAAC,CAAC,CAAC;wBACrB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,CAAC;4BAC3D,CAAC,GAAG,EAAE;gCACJ,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;gCAC3G,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gCAC7B,OAAO,KAAK,CAAC;4BACf,CAAC,CAAC,EAAE,CAAA;wBACN,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;wBAE1D,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;4BACtC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBACjC,CAAC;wBACD,MAAM;oBACR,CAAC;oBACD;wBACE,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAC7B,CAAC;gBACD,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;YACtB,CAAC;YACD,MAAM,EAAE,qBAAU;SACnB;QACD,UAAU,EAAE;YACV,IAAI,EAAE,EAAE;SACT;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAQ;IACjC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;AAC/C,CAAC;AAEY,QAAA,aAAa,GAAG;IAC3B,QAAQ;IACR,QAAQ;CACA,CAAA"}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import type { TimestampOutputState, TimestampOutputSettings } from "./runtime";
|
2
|
+
declare function InlineView({ state, config: _2 }: {
|
3
|
+
state: TimestampOutputState;
|
4
|
+
config: TimestampOutputSettings;
|
5
|
+
}): import("react/jsx-runtime").JSX.Element;
|
6
|
+
export default InlineView;
|
@@ -0,0 +1,95 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
7
|
+
const react_1 = require("react");
|
8
|
+
const auto_1 = __importDefault(require("chart.js/auto"));
|
9
|
+
function InlineView({ state, config: _2 }) {
|
10
|
+
const chartContainer = (0, react_1.useRef)(null);
|
11
|
+
const [chartControl, setChartControl] = (0, react_1.useState)(undefined);
|
12
|
+
(0, react_1.useEffect)(() => {
|
13
|
+
if (!chartContainer.current)
|
14
|
+
return;
|
15
|
+
if (state.timestamps.length < 2)
|
16
|
+
return;
|
17
|
+
auto_1.default.defaults.color = "#FFF";
|
18
|
+
const chart = new auto_1.default(chartContainer.current, {
|
19
|
+
type: 'line',
|
20
|
+
options: {
|
21
|
+
plugins: {
|
22
|
+
legend: {
|
23
|
+
display: false
|
24
|
+
},
|
25
|
+
},
|
26
|
+
animation: false,
|
27
|
+
color: '#FFF',
|
28
|
+
scales: {
|
29
|
+
x: {
|
30
|
+
min: 0,
|
31
|
+
max: 200,
|
32
|
+
grid: {
|
33
|
+
display: false,
|
34
|
+
}
|
35
|
+
},
|
36
|
+
y: {
|
37
|
+
min: 0,
|
38
|
+
max: 5000,
|
39
|
+
grid: {
|
40
|
+
display: false,
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
},
|
45
|
+
data: {
|
46
|
+
labels: new Array(200).fill(0).map((_, i) => i).map((_) => ""),
|
47
|
+
datasets: state.timestamps.map((t) => {
|
48
|
+
const mapped = (t.timestamps.map((f) => {
|
49
|
+
const elapsedWall = (f.wall - t.startTimeMs);
|
50
|
+
const elapsedTime = (f.ts - t.startTimestamp) * 1000.0;
|
51
|
+
return Math.abs(elapsedTime - elapsedWall);
|
52
|
+
}));
|
53
|
+
return {
|
54
|
+
label: t.key,
|
55
|
+
fill: false,
|
56
|
+
borderColor: 'rgba(255, 0, 0, 255)',
|
57
|
+
borderWidth: 1,
|
58
|
+
pointStyle: 'dash',
|
59
|
+
data: mapped
|
60
|
+
};
|
61
|
+
})
|
62
|
+
}
|
63
|
+
});
|
64
|
+
setChartControl(chart);
|
65
|
+
setInterval(() => {
|
66
|
+
chart.update();
|
67
|
+
}, 100);
|
68
|
+
}, [chartContainer]);
|
69
|
+
(0, react_1.useEffect)(() => {
|
70
|
+
if (!chartControl)
|
71
|
+
return;
|
72
|
+
chartControl.data = {
|
73
|
+
labels: new Array(200).fill(0).map((_, i) => i).map((_) => ""),
|
74
|
+
datasets: state.timestamps.map((t) => {
|
75
|
+
const mapped = (t.timestamps.map((f) => {
|
76
|
+
const elapsedWall = (f.wall - t.startTimeMs);
|
77
|
+
const elapsedTime = (f.ts - t.startTimestamp) * 1000.0;
|
78
|
+
return Math.abs(elapsedTime - elapsedWall);
|
79
|
+
}));
|
80
|
+
return {
|
81
|
+
label: t.key,
|
82
|
+
fill: false,
|
83
|
+
borderColor: 'rgba(255, 0, 0, 255)',
|
84
|
+
borderWidth: 1,
|
85
|
+
pointStyle: 'dash',
|
86
|
+
data: mapped
|
87
|
+
};
|
88
|
+
})
|
89
|
+
};
|
90
|
+
}, [state]);
|
91
|
+
{ }
|
92
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "util-timestamp", children: (0, jsx_runtime_1.jsx)("div", { className: "bg-gray-50 dark:bg-gray-700 rounded", style: { width: "360px", height: '200px', padding: '10px' }, children: (0, jsx_runtime_1.jsx)("canvas", { className: "bg-gray-50 dark:bg-gray-700 rounded", ref: chartContainer }) }) });
|
93
|
+
}
|
94
|
+
exports.default = InlineView;
|
95
|
+
//# sourceMappingURL=inline-view.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"inline-view.js","sourceRoot":"","sources":["../../src/util.timestamps/inline-view.tsx"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { Norsk } from '@norskvideo/norsk-sdk';
|
2
|
+
import { OnCreated, ServerComponentDefinition, ServerComponentSchemas, StudioRuntime } from '@norskvideo/norsk-studio/lib/extension/runtime-types';
|
3
|
+
import { SimpleSinkWrapper } from '@norskvideo/norsk-studio/lib/extension/base-nodes';
|
4
|
+
import { components } from './types';
|
5
|
+
export type TimestampOutputSettings = components['schemas']['TimestampOutputSettings'];
|
6
|
+
export type TimestampCollection = components['schemas']['TimestampCollection'];
|
7
|
+
export type TimestampOutputState = components['schemas']['TimestampOutputState'];
|
8
|
+
export type TimestampOutputEvent = components['schemas']['TimestampOutputEvent'];
|
9
|
+
export type TimestampOutputCommand = components['schemas']['TimestampOutputCommand'];
|
10
|
+
export default class TimestampOutputDefinition implements ServerComponentDefinition<TimestampOutputSettings, SimpleSinkWrapper, TimestampOutputState, TimestampOutputCommand, TimestampOutputEvent> {
|
11
|
+
schemas(): Promise<ServerComponentSchemas>;
|
12
|
+
create(norsk: Norsk, cfg: TimestampOutputSettings, cb: OnCreated<SimpleSinkWrapper>, runtime: StudioRuntime<TimestampOutputState, TimestampOutputCommand, TimestampOutputEvent>): Promise<void>;
|
13
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const base_nodes_1 = require("@norskvideo/norsk-studio/lib/extension/base-nodes");
|
7
|
+
const path_1 = __importDefault(require("path"));
|
8
|
+
const schemas_1 = require("../shared/schemas");
|
9
|
+
class TimestampOutputDefinition {
|
10
|
+
async schemas() {
|
11
|
+
return (0, schemas_1.schemaFromTypes)(path_1.default.join(__dirname, 'types.yaml'), {
|
12
|
+
config: 'TimestampOutputSettings',
|
13
|
+
state: 'TimestampOutputState'
|
14
|
+
});
|
15
|
+
}
|
16
|
+
async create(norsk, cfg, cb, runtime) {
|
17
|
+
const node = new TimestampOutput(norsk, runtime, cfg);
|
18
|
+
await node.initialised;
|
19
|
+
cb(node);
|
20
|
+
}
|
21
|
+
}
|
22
|
+
exports.default = TimestampOutputDefinition;
|
23
|
+
class TimestampOutput extends base_nodes_1.CustomSinkNode {
|
24
|
+
initialised;
|
25
|
+
norsk;
|
26
|
+
updates;
|
27
|
+
cfg;
|
28
|
+
node;
|
29
|
+
constructor(norsk, { updates }, cfg) {
|
30
|
+
super(cfg.id);
|
31
|
+
this.cfg = cfg;
|
32
|
+
this.norsk = norsk;
|
33
|
+
this.updates = updates;
|
34
|
+
this.initialised = this.initialise();
|
35
|
+
}
|
36
|
+
async initialise() {
|
37
|
+
const node = await this.norsk.inspect.streamTimestampReport({
|
38
|
+
onTimestamp: this.onTimestamp.bind(this)
|
39
|
+
});
|
40
|
+
this.setup({ sink: node });
|
41
|
+
}
|
42
|
+
onTimestamp(key, timestamp) {
|
43
|
+
this.updates.raiseEvent({
|
44
|
+
type: 'new-timestamp',
|
45
|
+
key: `${key.programNumber}-${key.sourceName}-${key.streamId}-${key.renditionName}`,
|
46
|
+
value: Number((timestamp.n * 100n) / timestamp.d) / 100,
|
47
|
+
wallMs: new Date().valueOf()
|
48
|
+
});
|
49
|
+
}
|
50
|
+
}
|
51
|
+
//# sourceMappingURL=runtime.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/util.timestamps/runtime.ts"],"names":[],"mappings":";;;;;AAGA,kFAAsG;AACtG,gDAAwB;AAGxB,+CAAoD;AAWpD,MAAqB,yBAAyB;IAC5C,KAAK,CAAC,OAAO;QACX,OAAO,IAAA,yBAAe,EAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE;YACzD,MAAM,EAAE,yBAAyB;YACjC,KAAK,EAAE,sBAAsB;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,KAAY,EAAE,GAA4B,EAAE,EAAgC,EAAE,OAA0F;QACnL,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,WAAW,CAAC;QACvB,EAAE,CAAC,IAAI,CAAC,CAAC;IACX,CAAC;CACF;AAZD,4CAYC;AAED,MAAM,eAAgB,SAAQ,2BAAc;IAC1C,WAAW,CAAgB;IAC3B,KAAK,CAAQ;IACb,OAAO,CAAqF;IAE5F,GAAG,CAA0B;IAC7B,IAAI,CAAyB;IAE7B,YAAY,KAAY,EAAE,EAAE,OAAO,EAAqF,EAAE,GAA4B;QACpJ,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACd,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC;YAC1D,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;SACzC,CAAC,CAAA;QACF,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5B,CAAC;IAED,WAAW,CAAC,GAAc,EAAE,SAAmB;QAC7C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;YACtB,IAAI,EAAE,eAAe;YACrB,GAAG,EAAE,GAAG,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,aAAa,EAAE;YAClF,KAAK,EAAE,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG;YACvD,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE;SAC7B,CAAC,CAAA;IACJ,CAAC;CACF"}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
export type paths = Record<string, never>;
|
2
|
+
export type webhooks = Record<string, never>;
|
3
|
+
export interface components {
|
4
|
+
schemas: {
|
5
|
+
TimestampOutputSettings: {
|
6
|
+
id: string;
|
7
|
+
displayName: string;
|
8
|
+
};
|
9
|
+
TimestampCollection: {
|
10
|
+
key: string;
|
11
|
+
timestamps: {
|
12
|
+
ts: number;
|
13
|
+
wall: number;
|
14
|
+
}[];
|
15
|
+
startTimestamp: number;
|
16
|
+
startTimeMs: number;
|
17
|
+
};
|
18
|
+
TimestampOutputState: {
|
19
|
+
timestamps: components["schemas"]["TimestampCollection"][];
|
20
|
+
};
|
21
|
+
TimestampOutputEvent: {
|
22
|
+
type: "new-timestamp";
|
23
|
+
key: string;
|
24
|
+
value: number;
|
25
|
+
wallMs: number;
|
26
|
+
};
|
27
|
+
TimestampOutputCommand: Record<string, never>;
|
28
|
+
};
|
29
|
+
responses: never;
|
30
|
+
parameters: never;
|
31
|
+
requestBodies: never;
|
32
|
+
headers: never;
|
33
|
+
pathItems: never;
|
34
|
+
}
|
35
|
+
export type $defs = Record<string, never>;
|
36
|
+
export type operations = Record<string, never>;
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/util.timestamps/types.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
openapi: 3.0.0
|
2
|
+
info:
|
3
|
+
title: Timestamp Output
|
4
|
+
version: 1.0.0
|
5
|
+
|
6
|
+
components:
|
7
|
+
schemas:
|
8
|
+
TimestampOutputSettings:
|
9
|
+
type: object
|
10
|
+
properties:
|
11
|
+
id:
|
12
|
+
type: string
|
13
|
+
displayName:
|
14
|
+
type: string
|
15
|
+
required:
|
16
|
+
- id
|
17
|
+
- displayName
|
18
|
+
|
19
|
+
TimestampCollection:
|
20
|
+
type: object
|
21
|
+
properties:
|
22
|
+
key:
|
23
|
+
type: string
|
24
|
+
timestamps:
|
25
|
+
type: array
|
26
|
+
items:
|
27
|
+
type: object
|
28
|
+
properties:
|
29
|
+
ts:
|
30
|
+
type: number
|
31
|
+
wall:
|
32
|
+
type: number
|
33
|
+
required:
|
34
|
+
- ts
|
35
|
+
- wall
|
36
|
+
startTimestamp:
|
37
|
+
type: number
|
38
|
+
startTimeMs:
|
39
|
+
type: number
|
40
|
+
required:
|
41
|
+
- key
|
42
|
+
- timestamps
|
43
|
+
- startTimestamp
|
44
|
+
- startTimeMs
|
45
|
+
|
46
|
+
TimestampOutputState:
|
47
|
+
type: object
|
48
|
+
properties:
|
49
|
+
timestamps:
|
50
|
+
type: array
|
51
|
+
items:
|
52
|
+
$ref: '#/components/schemas/TimestampCollection'
|
53
|
+
required:
|
54
|
+
- timestamps
|
55
|
+
|
56
|
+
TimestampOutputEvent:
|
57
|
+
type: object
|
58
|
+
properties:
|
59
|
+
type:
|
60
|
+
const: 'new-timestamp'
|
61
|
+
key:
|
62
|
+
type: string
|
63
|
+
value:
|
64
|
+
type: number
|
65
|
+
wallMs:
|
66
|
+
type: number
|
67
|
+
required:
|
68
|
+
- type
|
69
|
+
- key
|
70
|
+
- value
|
71
|
+
- wallMs
|
72
|
+
|
73
|
+
TimestampOutputCommand:
|
74
|
+
type: object
|
package/package.json
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
{
|
2
|
+
"name": "@norskvideo/norsk-studio-alpha",
|
3
|
+
"version": "1.27.0-2025-07-09-0fcad3ea",
|
4
|
+
"description": "",
|
5
|
+
"scripts": {
|
6
|
+
"clean": "rm -rf lib client build && make clean",
|
7
|
+
"types": "make -j 8",
|
8
|
+
"build": "npm run build-impl || true",
|
9
|
+
"build-impl": "npm run types && npx studio-wrap-infos src/ && npx npm-run-all build:* && rm -rf build",
|
10
|
+
"build:server": "npx tsc",
|
11
|
+
"build:client": "npx tsc -p tsconfig-client.json && npx studio-bundle build/info.js client/info.js",
|
12
|
+
"build:copy-css": "rsync --mkpath -v -r --include '*/' --include '*.css' --exclude '*' src/ client/",
|
13
|
+
"build:types": "rsync --mkpath -v -r --include '*/' --include '*.yaml' --exclude '*' src/ lib/",
|
14
|
+
"build:tailwind": "npx tailwindcss -i src/shared/tailwind.css -o client/style.css",
|
15
|
+
"build:eslint": "npx eslint src",
|
16
|
+
"test": "LOG_LEVEL=error mocha --no-parallel --jobs=0 --timeout 120000 --recursive lib/test"
|
17
|
+
},
|
18
|
+
"files": [
|
19
|
+
"client/*",
|
20
|
+
"lib/*",
|
21
|
+
"shared/*"
|
22
|
+
],
|
23
|
+
"license": "MIT",
|
24
|
+
"dependencies": {
|
25
|
+
"@apidevtools/json-schema-ref-parser": "^12.0.1",
|
26
|
+
"@norskvideo/norsk-sdk": "^1.0.402-2025-07-09-3593ca7e",
|
27
|
+
"@norskvideo/norsk-studio": "1.27.0-2025-07-09-0fcad3ea",
|
28
|
+
"@norskvideo/norsk-studio-built-ins": "1.27.0-2025-07-09-0fcad3ea",
|
29
|
+
"json-refs": "^3.0.15",
|
30
|
+
"JSX": "^1.1.0",
|
31
|
+
"node-fetch": "^2.7.0",
|
32
|
+
"openapi-types": "^12.1.3",
|
33
|
+
"react": "^18.3.0",
|
34
|
+
"react-dom": "^18.3.1",
|
35
|
+
"react-select": "^5.7.0"
|
36
|
+
},
|
37
|
+
"main": "lib/index.js",
|
38
|
+
"devDependencies": {
|
39
|
+
"@types/chai": "^4.3.11",
|
40
|
+
"@types/mocha": "^10.0.6",
|
41
|
+
"@types/node-fetch": "^2.6.9",
|
42
|
+
"@types/react": "^18.2.33",
|
43
|
+
"@types/react-dom": "^18.2.14",
|
44
|
+
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
45
|
+
"@typescript-eslint/parser": "^6.9.1",
|
46
|
+
"chai": "^4.3.10",
|
47
|
+
"esbuild": "^0.20.2",
|
48
|
+
"esbuild-plugin-external-global": "^1.0.1",
|
49
|
+
"eslint": "^8.53.0",
|
50
|
+
"hls-parser": "^0.10.8",
|
51
|
+
"mocha": "^10.4.0",
|
52
|
+
"npm-run-all": "^4.1.5",
|
53
|
+
"puppeteer": "^21.5.2",
|
54
|
+
"tailwindcss": "^3.4.1",
|
55
|
+
"typescript": "^5.4.5"
|
56
|
+
}
|
57
|
+
}
|