@norskvideo/norsk-sdk 1.0.402-2026-01-14-bf6be668 → 1.0.402-2026-01-16-61d8a916
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/lib/package.json +2 -2
- package/lib/src/media_nodes/output.d.ts +12 -0
- package/lib/src/media_nodes/output.js +3 -1
- package/lib/src/media_nodes/processor.d.ts +36 -14
- package/lib/src/media_nodes/processor.js +23 -43
- package/lib/src/media_nodes/types.d.ts +4 -0
- package/lib/src/media_nodes/types.js +3 -0
- package/package.json +2 -2
package/lib/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"license": "MIT",
|
|
3
3
|
"name": "@norskvideo/norsk-sdk",
|
|
4
|
-
"version": "1.0.402-2026-01-
|
|
4
|
+
"version": "1.0.402-2026-01-16-61d8a916+nightly",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@bufbuild/protobuf": "^0.3.0",
|
|
7
7
|
"@grpc/grpc-js": "~1.12.0",
|
|
8
|
-
"@norskvideo/norsk-api": "1.0.402-2026-01-
|
|
8
|
+
"@norskvideo/norsk-api": "1.0.402-2026-01-16-61d8a916+nightly",
|
|
9
9
|
"lodash": "^4.17.21",
|
|
10
10
|
"typescript-nullable": "^0.6.0"
|
|
11
11
|
},
|
|
@@ -1183,7 +1183,19 @@ export interface FileMp4OutputSettings extends SinkNodeSettings<FileMp4OutputNod
|
|
|
1183
1183
|
* Settings for encrypting the video track.
|
|
1184
1184
|
*/
|
|
1185
1185
|
videoEncryption?: EncryptionSettings;
|
|
1186
|
+
/**
|
|
1187
|
+
* Enable "incremental" write mode of non-fragmented mp4 output file. This periodically updates the file header (the moov) to
|
|
1188
|
+
* reflect the latest data that has been written, so that the file can be loaded/reloaded in some player while it is being written.
|
|
1189
|
+
* You must set {@link expectedMaxFileDurationS} to ensure an appropriate space can be reserved for the header or the file will no longer
|
|
1190
|
+
* update incrementally
|
|
1191
|
+
*/
|
|
1186
1192
|
enableIncrementalMp4Write?: boolean;
|
|
1193
|
+
/**
|
|
1194
|
+
* Maximum duration that the file is expected to last. This should be a conservative estimate according to the use case, so that you never
|
|
1195
|
+
* expect to hit the limit, but there is some file size cost to a larger value (so if the file is going to be 10 seconds, setting 2 hours would be a bad idea).
|
|
1196
|
+
*/
|
|
1197
|
+
incrementalWriteIntervalMs?: number;
|
|
1198
|
+
expectedMaxFileDurationS?: number;
|
|
1187
1199
|
}
|
|
1188
1200
|
/**
|
|
1189
1201
|
* @public
|
|
@@ -1502,7 +1502,9 @@ class FileMp4OutputNode extends common_2.AutoSinkMediaNode {
|
|
|
1502
1502
|
statsSampling: settings.statsSampling
|
|
1503
1503
|
? (0, utils_1.provideFull)(media_pb_1.StreamStatisticsSampling, settings.statsSampling)
|
|
1504
1504
|
: undefined,
|
|
1505
|
-
enableIncrementalMp4Write: !!settings.enableIncrementalMp4Write
|
|
1505
|
+
enableIncrementalMp4Write: !!settings.enableIncrementalMp4Write,
|
|
1506
|
+
incrementalWriteIntervalMs: settings.incrementalWriteIntervalMs ?? 0,
|
|
1507
|
+
expectedMaxFileDurationS: settings.expectedMaxFileDurationS ?? 0,
|
|
1506
1508
|
});
|
|
1507
1509
|
this.grpcStream = this.client.media.createOutputFileMp4();
|
|
1508
1510
|
this.grpcStream.write((0, utils_1.provideFull)(media_pb_1.FileMp4OutputMessage, (0, utils_1.mkMessageCase)({ configuration: config })));
|
|
@@ -159,6 +159,14 @@ export interface AudioMeasureLevelsSettings extends ProcessorNodeSettings<AudioM
|
|
|
159
159
|
*/
|
|
160
160
|
export declare class AudioMeasureLevelsNode extends AutoProcessorMediaNode<"audio"> {
|
|
161
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* @public
|
|
164
|
+
* Prompt to send periodically once setup is complete
|
|
165
|
+
*/
|
|
166
|
+
export type GeminiPeriodicPrompt = {
|
|
167
|
+
text: string;
|
|
168
|
+
intervalSeconds: number;
|
|
169
|
+
};
|
|
162
170
|
/**
|
|
163
171
|
* @public
|
|
164
172
|
* Recursive definition for defining types
|
|
@@ -166,6 +174,10 @@ export declare class AudioMeasureLevelsNode extends AutoProcessorMediaNode<"audi
|
|
|
166
174
|
export type Schema = {
|
|
167
175
|
type: "string";
|
|
168
176
|
description: string;
|
|
177
|
+
} | {
|
|
178
|
+
type: "enum";
|
|
179
|
+
values: string[];
|
|
180
|
+
description: string;
|
|
169
181
|
} | {
|
|
170
182
|
type: "number";
|
|
171
183
|
description: string;
|
|
@@ -189,6 +201,11 @@ export type Parameter = {
|
|
|
189
201
|
name: string;
|
|
190
202
|
description: string;
|
|
191
203
|
type: "string";
|
|
204
|
+
} | {
|
|
205
|
+
name: string;
|
|
206
|
+
description: string;
|
|
207
|
+
type: "enum";
|
|
208
|
+
values: string[];
|
|
192
209
|
} | {
|
|
193
210
|
name: string;
|
|
194
211
|
description: string;
|
|
@@ -210,7 +227,7 @@ export type Parameter = {
|
|
|
210
227
|
};
|
|
211
228
|
/**
|
|
212
229
|
* @public
|
|
213
|
-
* Definition for metadata passed as the first argument to
|
|
230
|
+
* Definition for metadata passed as the first argument to an AI function call
|
|
214
231
|
*/
|
|
215
232
|
export type FunctionCallMetadata = {
|
|
216
233
|
frameUtc?: Date;
|
|
@@ -224,7 +241,7 @@ export type FunctionDeclaration = {
|
|
|
224
241
|
description: string;
|
|
225
242
|
parameters: Parameter[];
|
|
226
243
|
response?: Schema;
|
|
227
|
-
function: (
|
|
244
|
+
function: (...args: any[]) => any | Promise<any>;
|
|
228
245
|
};
|
|
229
246
|
export type GeminiTextPart = {
|
|
230
247
|
partType: "text";
|
|
@@ -244,15 +261,16 @@ export type GeminiServerContent = {
|
|
|
244
261
|
interrupted: boolean;
|
|
245
262
|
parts: GeminiPart[];
|
|
246
263
|
};
|
|
247
|
-
export type
|
|
248
|
-
|
|
264
|
+
export type GeminiApiAuth = {
|
|
265
|
+
authType: "geminiApi";
|
|
266
|
+
googleApiKey: string;
|
|
249
267
|
};
|
|
250
|
-
export type
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
268
|
+
export type VertexAuth = {
|
|
269
|
+
authType: "vertex";
|
|
270
|
+
project: string;
|
|
271
|
+
location: string;
|
|
254
272
|
};
|
|
255
|
-
export type
|
|
273
|
+
export type GeminiAuth = GeminiApiAuth | VertexAuth;
|
|
256
274
|
/**
|
|
257
275
|
* @public
|
|
258
276
|
* Settings for Gemini Video
|
|
@@ -261,21 +279,25 @@ export interface GeminiVideoSettings {
|
|
|
261
279
|
resolution: Resolution;
|
|
262
280
|
frameRate: FrameRate;
|
|
263
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* @public
|
|
284
|
+
* Gemini status enumeration
|
|
285
|
+
*/
|
|
286
|
+
export type GeminiStatus = "connected" | "setupCompleted" | "turnComplete";
|
|
264
287
|
/**
|
|
265
288
|
* @public
|
|
266
289
|
* Settings for a GeminiProcessorNode
|
|
267
290
|
* see: {@link NorskControl.geminiProcessor}
|
|
268
291
|
*/
|
|
269
292
|
export interface GeminiSettings extends ProcessorNodeSettings<GeminiProcessorNode> {
|
|
270
|
-
|
|
293
|
+
auth: GeminiAuth;
|
|
271
294
|
model: string;
|
|
272
295
|
systemInstruction: string;
|
|
296
|
+
periodicPrompt?: GeminiPeriodicPrompt;
|
|
273
297
|
functions: FunctionDeclaration[];
|
|
274
|
-
apiChoice: GeminiApiChoice;
|
|
275
298
|
videoSettings?: GeminiVideoSettings;
|
|
276
|
-
|
|
277
|
-
contentCb?: (content:
|
|
278
|
-
contextCb?: (context: string) => void;
|
|
299
|
+
statusCb?: (status: GeminiStatus) => void;
|
|
300
|
+
contentCb?: (content: string) => void;
|
|
279
301
|
}
|
|
280
302
|
/**
|
|
281
303
|
* @public
|
|
@@ -414,6 +414,8 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
|
|
|
414
414
|
switch (schemaType) {
|
|
415
415
|
case "string":
|
|
416
416
|
return (0, utils_1.mkCase)({ stringType: (0, utils_1.provideFull)(media_pb_1.StringType, {}) });
|
|
417
|
+
case "enum":
|
|
418
|
+
return (0, utils_1.mkCase)({ enumType: (0, utils_1.provideFull)(media_pb_1.EnumType, { values: schema.values }) });
|
|
417
419
|
case "number":
|
|
418
420
|
return (0, utils_1.mkCase)({ numberType: (0, utils_1.provideFull)(media_pb_1.NumberType, {}) });
|
|
419
421
|
case "boolean":
|
|
@@ -443,6 +445,8 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
|
|
|
443
445
|
switch (schemaType) {
|
|
444
446
|
case "string":
|
|
445
447
|
return { type: "string", description: parameter.description };
|
|
448
|
+
case "enum":
|
|
449
|
+
return { type: "enum", description: parameter.description, values: parameter.values };
|
|
446
450
|
case "number":
|
|
447
451
|
return { type: "number", description: parameter.description };
|
|
448
452
|
case "boolean":
|
|
@@ -481,7 +485,16 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
|
|
|
481
485
|
id: settings.id
|
|
482
486
|
? (0, utils_1.provideFull)(media_pb_1.MediaNodeId, { id: settings.id })
|
|
483
487
|
: undefined,
|
|
484
|
-
|
|
488
|
+
auth: (() => {
|
|
489
|
+
switch (settings.auth.authType) {
|
|
490
|
+
case "geminiApi":
|
|
491
|
+
return (0, utils_1.mkCase)({ geminiApi: (0, utils_1.provideFull)(media_pb_1.GeminiConfiguration_GeminiApiAuth, { googleApiKey: settings.auth.googleApiKey }) });
|
|
492
|
+
case "vertex":
|
|
493
|
+
return (0, utils_1.mkCase)({ vertex: (0, utils_1.provideFull)(media_pb_1.GeminiConfiguration_VertexAuth, { project: settings.auth.project, location: settings.auth.location }) });
|
|
494
|
+
default:
|
|
495
|
+
(0, utils_1.exhaustiveCheck)(settings.auth);
|
|
496
|
+
}
|
|
497
|
+
})(),
|
|
485
498
|
model: settings.model,
|
|
486
499
|
systemInstruction: settings.systemInstruction,
|
|
487
500
|
functions: settings.functions.map((functionDeclaration) => (0, utils_1.provideFull)(media_pb_1.FunctionDeclaration, {
|
|
@@ -495,28 +508,6 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
|
|
|
495
508
|
})),
|
|
496
509
|
resolution: settings.videoSettings?.resolution ? (0, utils_1.provideFull)(media_pb_1.Resolution, settings.videoSettings.resolution) : undefined,
|
|
497
510
|
frameRate: settings.videoSettings ? (0, utils_1.provideFull)(media_pb_1.FrameRate, settings.videoSettings.frameRate) : undefined,
|
|
498
|
-
apiChoice: (() => {
|
|
499
|
-
if (settings.videoSettings == undefined) {
|
|
500
|
-
// No video, live is the only option for audio
|
|
501
|
-
return (0, utils_1.mkCase)({ liveApi: (0, utils_1.provideFull)(protobuf_1.Empty, {}) });
|
|
502
|
-
}
|
|
503
|
-
else {
|
|
504
|
-
const apiChoice = settings.apiChoice.apiType;
|
|
505
|
-
switch (apiChoice) {
|
|
506
|
-
case "live":
|
|
507
|
-
return (0, utils_1.mkCase)({ liveApi: (0, utils_1.provideFull)(protobuf_1.Empty, {}) });
|
|
508
|
-
case "singleShot":
|
|
509
|
-
return (0, utils_1.mkCase)({
|
|
510
|
-
"singleShotApi": (0, utils_1.provideFull)(media_pb_1.GeminiConfiguration_SingleShotApi, {
|
|
511
|
-
historicalContextMs: settings.apiChoice.historicalContextMs,
|
|
512
|
-
prompt: settings.apiChoice.prompt
|
|
513
|
-
})
|
|
514
|
-
});
|
|
515
|
-
default:
|
|
516
|
-
(0, utils_1.exhaustiveCheck)(apiChoice);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
})()
|
|
520
511
|
});
|
|
521
512
|
this.grpcStream = this.client.media.createGeminiProcessor();
|
|
522
513
|
this.grpcStream.write((0, utils_1.provideFull)(media_pb_1.GeminiRequest, (0, utils_1.mkMessageCase)({ configuration: geminiConfig })));
|
|
@@ -541,17 +532,17 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
|
|
|
541
532
|
break;
|
|
542
533
|
}
|
|
543
534
|
case "info": {
|
|
544
|
-
if (settings.
|
|
535
|
+
if (settings.statusCb) {
|
|
545
536
|
const v = data.message.value;
|
|
546
537
|
switch (v) {
|
|
547
538
|
case media_pb_1.GeminiInfo.CONNECTED:
|
|
548
|
-
settings.
|
|
549
|
-
break;
|
|
550
|
-
case media_pb_1.GeminiInfo.SETUP_STARTED:
|
|
551
|
-
settings.infoCb("setupStarted");
|
|
539
|
+
settings.statusCb("connected");
|
|
552
540
|
break;
|
|
553
541
|
case media_pb_1.GeminiInfo.SETUP_COMPLETED:
|
|
554
|
-
settings.
|
|
542
|
+
settings.statusCb("setupCompleted");
|
|
543
|
+
break;
|
|
544
|
+
case media_pb_1.GeminiInfo.TURN_COMPLETE:
|
|
545
|
+
settings.statusCb("turnComplete");
|
|
555
546
|
break;
|
|
556
547
|
default:
|
|
557
548
|
(0, utils_1.exhaustiveCheck)(v);
|
|
@@ -565,7 +556,7 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
|
|
|
565
556
|
if (declaration) {
|
|
566
557
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
567
558
|
const args = declaration.parameters.map(param => (0, common_1.valueToNative)(call.arguments[param.name]));
|
|
568
|
-
const response = declaration.function(
|
|
559
|
+
const response = declaration.function(...args);
|
|
569
560
|
if (response instanceof Promise) {
|
|
570
561
|
response.then((result) => {
|
|
571
562
|
const callResponse = (0, utils_1.provideFull)(media_pb_1.GeminiCallResponse, { name: call.name, id: call.id, response: { returnValue: (0, common_1.nativeToValue)(result) } });
|
|
@@ -587,20 +578,9 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
|
|
|
587
578
|
}
|
|
588
579
|
break;
|
|
589
580
|
}
|
|
590
|
-
case "
|
|
581
|
+
case "text": {
|
|
591
582
|
if (settings.contentCb) {
|
|
592
|
-
|
|
593
|
-
settings.contentCb({
|
|
594
|
-
turnComplete: content.turnComplete,
|
|
595
|
-
interrupted: content.interrupted,
|
|
596
|
-
parts: content.turn !== undefined ? content.turn.parts.map(GeminiProcessorNode.partFromPB) : []
|
|
597
|
-
});
|
|
598
|
-
}
|
|
599
|
-
break;
|
|
600
|
-
}
|
|
601
|
-
case "singleShotContext": {
|
|
602
|
-
if (settings.contextCb) {
|
|
603
|
-
settings.contextCb(data.message.value);
|
|
583
|
+
settings.contentCb(data.message.value);
|
|
604
584
|
}
|
|
605
585
|
break;
|
|
606
586
|
}
|
|
@@ -248,6 +248,10 @@ export interface X264Codec {
|
|
|
248
248
|
* Additional x264 command-line options in the format "--key value --key2 value2"
|
|
249
249
|
*/
|
|
250
250
|
extraOpts?: string;
|
|
251
|
+
/**
|
|
252
|
+
* CPUs to assign to this instance of x264, absent/empty array means use all CPUs
|
|
253
|
+
* */
|
|
254
|
+
cpuList?: number[];
|
|
251
255
|
}
|
|
252
256
|
/**
|
|
253
257
|
* @public
|
|
@@ -346,6 +346,7 @@ function toX264Codec(codec) {
|
|
|
346
346
|
tune: media_pb_1.X264Codec_X264Tune.UNDEFINED,
|
|
347
347
|
preset: media_pb_1.X264Codec_X264Preset.ULTRAFAST,
|
|
348
348
|
nalHrd: media_pb_1.X264Codec_X264NalHrd.UNDEFINED,
|
|
349
|
+
cpuList: []
|
|
349
350
|
};
|
|
350
351
|
codecOptions.threads = toOptInt(codec.threads);
|
|
351
352
|
if (codec.bitrateMode !== undefined)
|
|
@@ -385,6 +386,8 @@ function toX264Codec(codec) {
|
|
|
385
386
|
codecOptions.lookahead = mkOptInt(codec.lookahead);
|
|
386
387
|
if (codec.extraOpts !== undefined)
|
|
387
388
|
codecOptions.extraOpts = mkOptString(codec.extraOpts);
|
|
389
|
+
if (codec.cpuList !== undefined)
|
|
390
|
+
codecOptions.cpuList = codec.cpuList;
|
|
388
391
|
return (0, utils_1.provideFull)(media_pb_1.X264Codec, codecOptions);
|
|
389
392
|
}
|
|
390
393
|
exports.toX264Codec = toX264Codec;
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"license": "MIT",
|
|
3
3
|
"name": "@norskvideo/norsk-sdk",
|
|
4
|
-
"version": "1.0.402-2026-01-
|
|
4
|
+
"version": "1.0.402-2026-01-16-61d8a916+nightly",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@bufbuild/protobuf": "^0.3.0",
|
|
7
7
|
"@grpc/grpc-js": "~1.12.0",
|
|
8
|
-
"@norskvideo/norsk-api": "1.0.402-2026-01-
|
|
8
|
+
"@norskvideo/norsk-api": "1.0.402-2026-01-16-61d8a916+nightly",
|
|
9
9
|
"lodash": "^4.17.21",
|
|
10
10
|
"typescript-nullable": "^0.6.0"
|
|
11
11
|
},
|