@norskvideo/norsk-sdk 1.0.350 → 1.0.351

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.
@@ -102,6 +102,7 @@ export declare class AudioBuildMultichannelNode extends AutoProcessorMediaNode<"
102
102
  export declare interface AudioBuildMultichannelSettings extends ProcessorNodeSettings<AudioBuildMultichannelNode> {
103
103
  /** The channel layout of the built outgoing stream */
104
104
  channelLayout: ChannelLayout;
105
+ sampleRate: SampleRate;
105
106
  /**
106
107
  * Stream keys specifying the source for each channel, where the order is
107
108
  * significant. The streams must all have the same sample format and sample
@@ -452,8 +453,13 @@ export declare interface AudioTranscribeWhisperSettings extends ProcessorNodeSet
452
453
  noFallback?: boolean;
453
454
  numThreads?: number;
454
455
  useGpu?: boolean;
455
- language: string;
456
+ language?: string;
456
457
  model: string;
458
+ translate?: boolean;
459
+ tinyDiarize?: boolean;
460
+ initialPrompt?: string;
461
+ suppressNonSpeechTokens?: boolean;
462
+ samplingStrategy?: WhisperSamplingStrategy;
457
463
  }
458
464
 
459
465
  export declare interface AutoProcessorMediaNode<Pins extends string> extends SourceMediaNode, AutoSinkMediaNode<Pins> {
@@ -1348,6 +1354,8 @@ export declare class FileTsOutputNode extends AutoSinkMediaNode<"audio" | "video
1348
1354
  export declare interface FileTsOutputSettings extends SinkNodeSettings<FileTsOutputNode>, StreamStatisticsMixin {
1349
1355
  /** The file to write - this will be truncated if it already exist */
1350
1356
  fileName: string;
1357
+ /** A/V delay in milliseconds - to allow inclusion of subtitles, metadata and other ancillary data. May be set to 0 if these are not present to reduce latency */
1358
+ avDelayMs?: number;
1351
1359
  }
1352
1360
 
1353
1361
  /**
@@ -1363,12 +1371,40 @@ export declare interface FrameRate {
1363
1371
  seconds: number;
1364
1372
  }
1365
1373
 
1374
+ /** @public */
1366
1375
  export declare type FrameStoreCut = {
1367
1376
  startDateTime: Date;
1368
1377
  durationMs: number;
1369
1378
  sessionNum?: number;
1370
1379
  };
1371
1380
 
1381
+ /** @public */
1382
+ export declare type FrameStoreCutRequest = {
1383
+ fileFormat: "mp4";
1384
+ id: string;
1385
+ streamSelection: FrameStoreStreamSelection;
1386
+ cuts: FrameStoreCut[];
1387
+ trimPartialSegments: boolean;
1388
+ fileName: string;
1389
+ progressCb: (progress: number) => void;
1390
+ completeCb: (size: bigint) => void;
1391
+ };
1392
+
1393
+ /** @public */
1394
+ export declare type FrameStoreExpireBySize = {
1395
+ expire: "bySize";
1396
+ size: number;
1397
+ };
1398
+
1399
+ /** @public */
1400
+ export declare type FrameStoreExpireByTime = {
1401
+ expire: "byTime";
1402
+ durationS: number;
1403
+ };
1404
+
1405
+ /** @public */
1406
+ export declare type FrameStoreExpiry = FrameStoreExpireBySize | FrameStoreExpireByTime;
1407
+
1372
1408
  /**
1373
1409
  * @public
1374
1410
  * see: {@link NorskInput.frameStorePlayer}
@@ -1407,6 +1443,7 @@ export declare interface FrameStorePlayerSettings extends InputSettings<FrameSto
1407
1443
  * see: {@link NorskOutput.frameStoreRecording}
1408
1444
  */
1409
1445
  export declare class FrameStoreRecorderNode extends AutoSinkMediaNode<"audio" | "video"> {
1446
+ makeCut(request: FrameStoreCutRequest): void;
1410
1447
  }
1411
1448
 
1412
1449
  /**
@@ -1427,8 +1464,13 @@ export declare interface FrameStoreRecorderSettings extends SinkNodeSettings<Fra
1427
1464
  * Required: Duration of the frame store chunk files
1428
1465
  */
1429
1466
  chunkFileDurationSeconds: number;
1467
+ /**
1468
+ * Optional: Expiry settings - if not supplied, then data will *not* get expired so on long-running events you may exhaust available disk space
1469
+ */
1470
+ expiry?: FrameStoreExpiry;
1430
1471
  }
1431
1472
 
1473
+ /** @public */
1432
1474
  export declare type FrameStoreStreamSelection = "all" | StreamKey[];
1433
1475
 
1434
1476
  export declare function fromVancPayloadFormat(format: VancPayloadFormat_2): VancPayloadFormat;
@@ -1962,6 +2004,14 @@ export declare interface MediaSegment {
1962
2004
  number?: number;
1963
2005
  }
1964
2006
 
2007
+ export declare class MetadataCombineMode extends AutoProcessorMediaNode<"ancillary"> {
2008
+ }
2009
+
2010
+ export declare interface MetadataCombineSettings extends ProcessorNodeSettings<MetadataCombineMode> {
2011
+ outputStreamKey: StreamKey;
2012
+ maxSyncDelta?: number;
2013
+ }
2014
+
1965
2015
  /**
1966
2016
  * @public
1967
2017
  * Generate encryption parameters from from an encryption KeyID and Key,
@@ -2577,7 +2627,15 @@ export declare interface NorskTransform {
2577
2627
  * hundred milliseconds
2578
2628
  */
2579
2629
  streamAlign(settings: StreamAlignSettings): Promise<StreamAlignNode>;
2630
+ /**
2631
+ * Observe, modify or inject ancillary data such as SCTE-35
2632
+ */
2580
2633
  ancillary(settings: AncillarySettings): Promise<AncillaryNode>;
2634
+ /**
2635
+ * Combine compatible streams of metadata (this refers to ancillary streams of metadata messages, such as that
2636
+ * carried in an MPEG-TS PES metadata stream (e.g. KLV), unrelated to operations on the metadata of audio/video/etc streams.
2637
+ */
2638
+ metadataCombine(settings: MetadataCombineSettings): Promise<MetadataCombineMode>;
2581
2639
  }
2582
2640
 
2583
2641
  /** @public */
@@ -3043,6 +3101,8 @@ export declare interface RtmpOutputSettings extends SinkNodeSettings<RtmpOutputN
3043
3101
  url: string;
3044
3102
  /** Jitter buffer delay in milliseconds */
3045
3103
  bufferDelayMs?: number;
3104
+ /** A/V delay in milliseconds (to allow embedded captions to be added) */
3105
+ avDelayMs?: number;
3046
3106
  /** Called when the RTMP output succesfully connects to a server and starts publishing data */
3047
3107
  onPublishStart?: () => void;
3048
3108
  /** Called when the connection to the RTMP server fails */
@@ -3467,7 +3527,28 @@ export declare type Scte35TimeSignalCommand = {
3467
3527
  spliceTime: Scte35SpliceTime;
3468
3528
  };
3469
3529
 
3470
- /** @public */
3530
+ /**
3531
+ * @public
3532
+ * Select all the streams from the input
3533
+ * @param streams - The streams from the inbound Context
3534
+ * @returns Array of selected StreamKeys
3535
+ */
3536
+ export declare function selectAll(streams: readonly StreamMetadata[]): StreamKey[];
3537
+
3538
+ /**
3539
+ * @public
3540
+ * Select all the ancillary data streams from the input
3541
+ * @param streams - The streams from the inbound Context
3542
+ * @returns Array of selected StreamKeys
3543
+ */
3544
+ export declare function selectAncillary(streams: readonly StreamMetadata[]): StreamKey[];
3545
+
3546
+ /**
3547
+ * @public
3548
+ * Select all the audio streams from the input
3549
+ * @param streams - The streams from the inbound Context
3550
+ * @returns Array of selected StreamKeys
3551
+ */
3471
3552
  export declare function selectAudio(streams: readonly StreamMetadata[]): StreamKey[];
3472
3553
 
3473
3554
  /**
@@ -3484,13 +3565,28 @@ export declare function selectExactKey(key: StreamKey): (streams: readonly Strea
3484
3565
  /** @public */
3485
3566
  export declare function selectPlaylist(streams: readonly StreamMetadata[]): StreamKey[];
3486
3567
 
3487
- /** @public */
3568
+ /**
3569
+ * @public
3570
+ * Select all the subtitle streams from the input
3571
+ * @param streams - The streams from the inbound Context
3572
+ * @returns Array of selected StreamKeys
3573
+ */
3488
3574
  export declare function selectSubtitles(streams: readonly StreamMetadata[]): StreamKey[];
3489
3575
 
3490
- /** @public */
3576
+ /**
3577
+ * @public
3578
+ * Select all the video streams from the input
3579
+ * @param streams - The streams from the inbound Context
3580
+ * @returns Array of selected StreamKeys
3581
+ */
3491
3582
  export declare function selectVideo(streams: readonly StreamMetadata[]): StreamKey[];
3492
3583
 
3493
- /** @public */
3584
+ /**
3585
+ * @public
3586
+ * Create a selector selecting all the video streams from the input with the specified rendition name
3587
+ * @param renditionName - The streams from the inbound Context
3588
+ * @returns Array of selected StreamKeys
3589
+ */
3494
3590
  export declare function selectVideoRendition(renditionName: string): (streams: readonly StreamMetadata[]) => StreamKey[];
3495
3591
 
3496
3592
  /** @public */
@@ -3715,6 +3811,8 @@ export declare interface SrtOutputSettings extends SinkNodeSettings<SrtOutputNod
3715
3811
  port: number;
3716
3812
  /** Jitter buffer delay in milliseconds */
3717
3813
  bufferDelayMs?: number;
3814
+ /** A/V delay in milliseconds - to allow inclusion of subtitles, metadata and other ancillary data. May be set to 0 if these are not present to reduce latency */
3815
+ avDelayMs?: number;
3718
3816
  /**
3719
3817
  * On connect callback, notifying that a new caller has connected (in listener mode) and providing the stream_id that was set on the socket
3720
3818
  * @eventProperty
@@ -3958,6 +4056,17 @@ export declare interface StreamSwitchHardSettings<Pins extends string> extends P
3958
4056
  outputSource: string;
3959
4057
  }
3960
4058
 
4059
+ /** @public */
4060
+ export declare type StreamSwitchSmoothHardwareAcceleration =
4061
+ /**
4062
+ * Use the quadra overlay functionality to perform the compose
4063
+ */
4064
+ "quadra"
4065
+ /**
4066
+ * Use an nvidia CUDA kernel to perform the compose
4067
+ */
4068
+ | "nvidia";
4069
+
3961
4070
  /**
3962
4071
  * @public
3963
4072
  * see: {@link NorskControl.streamSwitchSmooth}
@@ -4014,6 +4123,10 @@ export declare interface StreamSwitchSmoothSettings<Pins extends string> extends
4014
4123
  * @param allStreams The collection of input contexts received over all input pins
4015
4124
  */
4016
4125
  onInboundContextChange?: (allStreams: Map<Pins, StreamMetadata[]>) => Promise<void>;
4126
+ /**
4127
+ * Optionally attempt to perform the compose operation on hardware
4128
+ */
4129
+ hardwareAcceleration?: ComposeHardwareAcceleration;
4017
4130
  }
4018
4131
 
4019
4132
  /**
@@ -4108,8 +4221,10 @@ export declare type SubscriptionError = {
4108
4221
  * - false/deny: Deny the incoming context, if no context has been accepted, then queue data until one is
4109
4222
  * - accept_and_terminate: Allow the incoming context, then deny further data, flush and shut down the node
4110
4223
  * this is useful for cleanly terminating outputs when the context is empty
4224
+ * - deny_and_queue: Deny the incoming context, and revert to the original queueing behaviour as if no context has been accepted
4225
+ * this is useful when switching from one full context to another, avoiding any "in-between"
4111
4226
  * */
4112
- export declare type SubscriptionValidationResponse = true | false | "accept" | "deny" | "accept_and_terminate";
4227
+ export declare type SubscriptionValidationResponse = true | false | "accept" | "deny" | "accept_and_terminate" | "deny_and_queue";
4113
4228
 
4114
4229
  /** @public */
4115
4230
  export declare function subtitlesToPin<Pins extends string>(pin: Pins): (streams: StreamMetadata[]) => PinToKey<Pins>;
@@ -4203,6 +4318,8 @@ export declare interface UdpTsOutputSettings extends SinkNodeSettings<UdpTsOutpu
4203
4318
  port: number;
4204
4319
  /** Jitter buffer delay in milliseconds */
4205
4320
  bufferDelayMs?: number;
4321
+ /** A/V delay in milliseconds - to allow inclusion of subtitles, metadata and other ancillary data. May be set to 0 if these are not present to reduce latency */
4322
+ avDelayMs?: number;
4206
4323
  /** Whether to encapsulate in RTP via RFC 2250 (default: false) */
4207
4324
  rtpEncapsulate?: boolean;
4208
4325
  }
@@ -4558,6 +4675,14 @@ export declare interface WhipOutputSettings extends SinkNodeSettings<WhipOutputN
4558
4675
  bufferDelayMs?: number;
4559
4676
  }
4560
4677
 
4678
+ declare type WhisperSamplingStrategy = {
4679
+ strategy: 'greedy';
4680
+ bestOf?: number;
4681
+ } | {
4682
+ strategy: "beam_search";
4683
+ beam_size?: number;
4684
+ };
4685
+
4561
4686
  /** @public */
4562
4687
  export declare interface X264Codec {
4563
4688
  type: "x264";
@@ -4768,9 +4893,9 @@ export declare type X265Tune = "psnr" | "ssim" | "grain" | "zerolatency" | "fast
4768
4893
 
4769
4894
  /**
4770
4895
  * @public
4771
- * Settings for a H264 Encode using Netint Xilinx hardware
4896
+ * Settings for a H264 Encode using Xilinx hardware
4772
4897
  * A detailed description of these params can be found
4773
- * on the Netint Xilinx Encoder Documentation
4898
+ * on the Xilinx Encoder Documentation
4774
4899
  *
4775
4900
  * These fields have deliberately been written to maintain the same semantics as the
4776
4901
  * Xilinx documentation where possible.
@@ -4781,6 +4906,13 @@ export declare interface XilinxH264 {
4781
4906
  type: "xilinx-h264";
4782
4907
  profile?: XilinxH264Profile;
4783
4908
  level?: XilinxH264Level;
4909
+ rateControl?: XilinxRateControl;
4910
+ lookaheadDepth?: number;
4911
+ idrPeriod?: number;
4912
+ bframes?: number;
4913
+ gopSize?: number;
4914
+ minQp?: number;
4915
+ maxQp?: number;
4784
4916
  }
4785
4917
 
4786
4918
  /** @public */
@@ -4791,9 +4923,9 @@ export declare type XilinxH264Profile = "baseline" | "main" | "extended" | "high
4791
4923
 
4792
4924
  /**
4793
4925
  * @public
4794
- * Settings for a HEVC Encode using Netint Xilinx hardware
4926
+ * Settings for a HEVC Encode using Xilinx hardware
4795
4927
  * A detailed description of these params can be found
4796
- * on the Netint Xilinx Encoder Documentation
4928
+ * on the Xilinx Encoder Documentation
4797
4929
  *
4798
4930
  * These fields have deliberately been written to maintain the same semantics as the
4799
4931
  * Xilinx documentation where possible.
@@ -4816,4 +4948,10 @@ export declare type XilinxHevcProfile = "main" | "main10";
4816
4948
  /** @public */
4817
4949
  export declare type XilinxHevcTier = "main" | "high";
4818
4950
 
4951
+ /** @public */
4952
+ export declare interface XilinxRateControl {
4953
+ value: number;
4954
+ mode: "constQp" | "cbr" | "vbr" | "lowLatency";
4955
+ }
4956
+
4819
4957
  export { }
@@ -94,8 +94,10 @@ export declare class SourceMediaNode extends MediaNodeState {
94
94
  * - false/deny: Deny the incoming context, if no context has been accepted, then queue data until one is
95
95
  * - accept_and_terminate: Allow the incoming context, then deny further data, flush and shut down the node
96
96
  * this is useful for cleanly terminating outputs when the context is empty
97
+ * - deny_and_queue: Deny the incoming context, and revert to the original queueing behaviour as if no context has been accepted
98
+ * this is useful when switching from one full context to another, avoiding any "in-between"
97
99
  * */
98
- export declare type SubscriptionValidationResponse = true | false | "accept" | "deny" | "accept_and_terminate";
100
+ export declare type SubscriptionValidationResponse = true | false | "accept" | "deny" | "accept_and_terminate" | "deny_and_queue";
99
101
  /** @public */
100
102
  export declare class SinkMediaNode<Pins extends string> extends MediaNodeState implements SubscribeDestination {
101
103
  permissiveSubscriptionValidation(_context: Context): SubscriptionValidationResponse;
@@ -114,22 +114,37 @@ class SourceMediaNode extends MediaNodeState {
114
114
  /** @internal */
115
115
  subscriptionComplete(context, subscriber) {
116
116
  return () => {
117
- const pending = this.pendingContextAcks.get(context);
118
- if (pending === undefined)
117
+ const pending = this.pendingContextAcks.get(context.blockingCallRef);
118
+ if (pending === undefined) {
119
+ // Subscription completed before even adding it!!
120
+ // should never happen now
121
+ (0, utils_1.errorlog)("No pending subscription found for ref %s on %s, something went horribly wrong", context.blockingCallRef, this.id);
119
122
  return;
120
- (0, utils_1.debuglog)("Checking context on %s: %O", this.id, context.blockingCallRef);
121
- if (pending.length == 1) {
122
- (0, utils_1.debuglog)("Node '%s' acknowledging context %O", this.id, context.blockingCallRef);
123
- _ackContext(this.client, this.id, context);
124
- this.pendingContextAcks.delete(context);
125
- }
126
- else {
127
- let index = pending.indexOf(subscriber); // should error if not null?
128
- this.pendingContextAcks.set(context, pending.splice(index, 1));
129
123
  }
124
+ ;
125
+ let index = pending.pendingSubscribes.indexOf(subscriber);
126
+ pending.pendingSubscribes.splice(index, 1);
127
+ this.maybeAckPendingContext(context);
130
128
  };
131
129
  }
132
130
  /** @internal */
131
+ maybeAckPendingContext(context) {
132
+ const pending = this.pendingContextAcks.get(context.blockingCallRef);
133
+ if (!pending) {
134
+ (0, utils_1.errorlog)("No pending subscription found for ref %s on %s, something went horribly wrong", context.blockingCallRef, this.id);
135
+ return;
136
+ }
137
+ (0, utils_1.debuglog)("Checking context on %s: %O", this.id, context.blockingCallRef);
138
+ if (pending.pendingSubscribes.length == 0 && pending.readyToAck) {
139
+ (0, utils_1.debuglog)("Node '%s' acknowledging context %O", this.id, context.blockingCallRef);
140
+ _ackContext(this.client, this.id, context);
141
+ this.pendingContextAcks.delete(context.blockingCallRef);
142
+ }
143
+ else {
144
+ (0, utils_1.debuglog)("Node '%s' not acknowledging context yet, pending: %d %O", this.id, pending.pendingSubscribes.length, context.blockingCallRef);
145
+ }
146
+ }
147
+ /** @internal */
133
148
  outboundContextChange(context) {
134
149
  return __awaiter(this, void 0, void 0, function* () {
135
150
  (0, utils_1.debuglog)("Node '%s' received new outbound context %O", this.id, debugFormatContext(context));
@@ -138,23 +153,22 @@ class SourceMediaNode extends MediaNodeState {
138
153
  if (this.onOutboundContextChange) {
139
154
  yield this.onOutboundContextChange(this.outputStreams);
140
155
  }
141
- let pending = [];
156
+ let pending = { pendingSubscribes: [], readyToAck: false };
157
+ this.pendingContextAcks.set(context.blockingCallRef, pending);
142
158
  for (let [subscriber, _] of this.subscribers) {
159
+ // Okay, this is async
160
+ // which means that while one is executing, another can complete
161
+ // and that just messes the whole world up beause we haven't stashed it away yet!
143
162
  const alive = yield subscriber.sourceContextChange(this.subscriptionComplete(context, subscriber));
144
163
  if (alive) {
145
- pending.push(subscriber);
164
+ pending.pendingSubscribes.push(subscriber);
146
165
  }
147
166
  else {
148
167
  (0, utils_1.debuglog)("Skipping updating subscription to closed node %s", subscriber.id);
149
168
  }
150
169
  }
151
- if (pending.length > 0) {
152
- this.pendingContextAcks.set(context, pending);
153
- }
154
- else {
155
- (0, utils_1.debuglog)("Node '%s' acknowledging context immediately %O", this.id, context.blockingCallRef);
156
- _ackContext(this.client, this.id, context);
157
- }
170
+ pending.readyToAck = true;
171
+ this.maybeAckPendingContext(context);
158
172
  });
159
173
  }
160
174
  }
@@ -365,6 +379,8 @@ class SinkMediaNode extends MediaNodeState {
365
379
  return media_pb_1.ValidationResponse_ContextValidationResponse.CONTEXT_VALIDATION_DENY;
366
380
  case "accept_and_terminate":
367
381
  return media_pb_1.ValidationResponse_ContextValidationResponse.CONTEXT_VALIDATION_ALLOW_AND_TERMINATE;
382
+ case "deny_and_queue":
383
+ return media_pb_1.ValidationResponse_ContextValidationResponse.CONTEXT_VALIDATION_DENY_AND_QUEUE;
368
384
  default:
369
385
  (0, utils_1.exhaustiveCheck)(response);
370
386
  }
@@ -1,7 +1,7 @@
1
1
  import * as grpc from "@grpc/grpc-js";
2
2
  import { MediaClient } from "@norskvideo/norsk-api/lib/media_grpc_pb";
3
3
  import { TsInputEvent, StreamKey as StreamKeyPB, Wave, FileTsInputMessage, UdpTsInputMessage, TimestampProgramNudge, RtmpError_UnsupportedVideo, RtmpError_UnsupportedAudio } from "@norskvideo/norsk-api/lib/media_pb";
4
- import { BrowserEvent, ChannelLayout, RtmpServerInputStatus, RtpLinearPcmBitDepth, SampleFormat, SampleRate, SrtMode, SrtInputStatus, ImageFormat, IceServerSettings, StreamKey } from "./types";
4
+ import { BrowserEvent, ChannelLayout, RtmpServerInputStatus, RtpLinearPcmBitDepth, SampleFormat, SampleRate, SrtMode, SrtInputStatus, ImageFormat, IceServerSettings, FrameStoreStreamSelection, FrameStoreCut } from "./types";
5
5
  import { FrameRate } from "../types";
6
6
  import { DeckLinkPixelFormat, DeckLinkVideoConnection, DeckLinkDisplayModeId } from "../types";
7
7
  import { MediaNodeState, SourceMediaNode, SourceNodeSettings, StreamStatisticsMixin } from "./common";
@@ -602,12 +602,6 @@ export declare class FileMp4InputNode extends SourceMediaNode {
602
602
  nudge(nudge: number): void;
603
603
  updateSettings(settings: FileMp4InputSettingsUpdate): void;
604
604
  }
605
- export declare type FrameStoreStreamSelection = "all" | StreamKey[];
606
- export declare type FrameStoreCut = {
607
- startDateTime: Date;
608
- durationMs: number;
609
- sessionNum?: number;
610
- };
611
605
  /**
612
606
  * @public
613
607
  * Settings for Frame Store playback
@@ -1246,13 +1246,13 @@ class FrameStorePlayerNode extends common_1.SourceMediaNode {
1246
1246
  durationMs,
1247
1247
  sessionNum: sessionNum ? (0, utils_1.provideFull)(common_pb_1.OptionalInt, { value: sessionNum }) : undefined
1248
1248
  })),
1249
- streamSelection: (settings.streamSelection == "all") ?
1250
- (0, utils_1.mkCase)({ all: (0, utils_1.provideFull)(media_pb_1.FrameStorePlayerConfiguration_All, {}) }) :
1251
- (0, utils_1.mkCase)({
1252
- subset: (0, utils_1.provideFull)(media_pb_1.FrameStorePlayerConfiguration_Subset, {
1253
- streamList: settings.streamSelection.map(types_1.mkStreamKey)
1254
- })
1255
- }),
1249
+ streamSelection: (0, utils_1.provideFull)(media_pb_1.StreamSelection, { streamSelection: (settings.streamSelection == "all") ?
1250
+ (0, utils_1.mkCase)({ all: (0, utils_1.provideFull)(media_pb_1.StreamSelection_All, {}) }) :
1251
+ (0, utils_1.mkCase)({
1252
+ subset: (0, utils_1.provideFull)(media_pb_1.StreamSelection_Subset, {
1253
+ streamList: settings.streamSelection.map(types_1.mkStreamKey)
1254
+ })
1255
+ }) }),
1256
1256
  trimPartialSegments: settings.trimPartialSegments
1257
1257
  });
1258
1258
  this.grpcStream = client.createInputFrameStorePlayer();
@@ -1,7 +1,7 @@
1
1
  import * as grpc from "@grpc/grpc-js";
2
2
  import { MediaClient } from "@norskvideo/norsk-api/lib/media_grpc_pb";
3
3
  import { CmafAudioMessage, CmafMultiVariantMessage, CmafVideoMessage, CmafWebVttMessage, HlsOutputEvent, HlsTsAudioMessage, HlsTsCombinedPushMessage, HlsTsVideoMessage, Subscription, HlsTsMultiVariantMessage } from "@norskvideo/norsk-api/lib/media_pb";
4
- import { AwsCredentials, EncryptionSettings, IceServerSettings, SrtMode, StreamMetadata, Scte35SpliceInfoSection } from "./types";
4
+ import { AwsCredentials, EncryptionSettings, IceServerSettings, SrtMode, StreamMetadata, Scte35SpliceInfoSection, FrameStoreStreamSelection, FrameStoreCut } from "./types";
5
5
  import { AutoProcessorMediaNode, ProcessorNodeSettings } from "./processor";
6
6
  import { AutoSinkMediaNode, MediaNodeState, SinkNodeSettings, StreamStatisticsMixin } from "./common";
7
7
  /**
@@ -616,6 +616,8 @@ export interface UdpTsOutputSettings extends SinkNodeSettings<UdpTsOutputNode>,
616
616
  port: number;
617
617
  /** Jitter buffer delay in milliseconds */
618
618
  bufferDelayMs?: number;
619
+ /** A/V delay in milliseconds - to allow inclusion of subtitles, metadata and other ancillary data. May be set to 0 if these are not present to reduce latency */
620
+ avDelayMs?: number;
619
621
  /** Whether to encapsulate in RTP via RFC 2250 (default: false) */
620
622
  rtpEncapsulate?: boolean;
621
623
  }
@@ -653,6 +655,8 @@ export interface SrtOutputSettings extends SinkNodeSettings<SrtOutputNode>, Stre
653
655
  port: number;
654
656
  /** Jitter buffer delay in milliseconds */
655
657
  bufferDelayMs?: number;
658
+ /** A/V delay in milliseconds - to allow inclusion of subtitles, metadata and other ancillary data. May be set to 0 if these are not present to reduce latency */
659
+ avDelayMs?: number;
656
660
  /**
657
661
  * On connect callback, notifying that a new caller has connected (in listener mode) and providing the stream_id that was set on the socket
658
662
  * @eventProperty
@@ -731,6 +735,8 @@ export interface RtmpOutputSettings extends SinkNodeSettings<RtmpOutputNode>, St
731
735
  url: string;
732
736
  /** Jitter buffer delay in milliseconds */
733
737
  bufferDelayMs?: number;
738
+ /** A/V delay in milliseconds (to allow embedded captions to be added) */
739
+ avDelayMs?: number;
734
740
  /** Called when the RTMP output succesfully connects to a server and starts publishing data */
735
741
  onPublishStart?: () => void;
736
742
  /** Called when the connection to the RTMP server fails */
@@ -758,6 +764,8 @@ export declare class RtmpOutputNode extends AutoSinkMediaNode<"audio" | "video">
758
764
  export interface FileTsOutputSettings extends SinkNodeSettings<FileTsOutputNode>, StreamStatisticsMixin {
759
765
  /** The file to write - this will be truncated if it already exist */
760
766
  fileName: string;
767
+ /** A/V delay in milliseconds - to allow inclusion of subtitles, metadata and other ancillary data. May be set to 0 if these are not present to reduce latency */
768
+ avDelayMs?: number;
761
769
  }
762
770
  /**
763
771
  * @public
@@ -806,6 +814,29 @@ export declare class FileMp4OutputNode extends AutoSinkMediaNode<"audio" | "vide
806
814
  */
807
815
  writeFile(nonfragmentedFileName: string): void;
808
816
  }
817
+ /** @public */
818
+ export declare type FrameStoreExpireByTime = {
819
+ expire: "byTime";
820
+ durationS: number;
821
+ };
822
+ /** @public */
823
+ export declare type FrameStoreExpireBySize = {
824
+ expire: "bySize";
825
+ size: number;
826
+ };
827
+ /** @public */
828
+ export declare type FrameStoreExpiry = FrameStoreExpireBySize | FrameStoreExpireByTime;
829
+ /** @public */
830
+ export declare type FrameStoreCutRequest = {
831
+ fileFormat: "mp4";
832
+ id: string;
833
+ streamSelection: FrameStoreStreamSelection;
834
+ cuts: FrameStoreCut[];
835
+ trimPartialSegments: boolean;
836
+ fileName: string;
837
+ progressCb: (progress: number) => void;
838
+ completeCb: (size: bigint) => void;
839
+ };
809
840
  /**
810
841
  * @public
811
842
  * Settings to configure a frame store recorder
@@ -824,12 +855,17 @@ export interface FrameStoreRecorderSettings extends SinkNodeSettings<FrameStoreR
824
855
  * Required: Duration of the frame store chunk files
825
856
  */
826
857
  chunkFileDurationSeconds: number;
858
+ /**
859
+ * Optional: Expiry settings - if not supplied, then data will *not* get expired so on long-running events you may exhaust available disk space
860
+ */
861
+ expiry?: FrameStoreExpiry;
827
862
  }
828
863
  /**
829
864
  * @public
830
865
  * see: {@link NorskOutput.frameStoreRecording}
831
866
  */
832
867
  export declare class FrameStoreRecorderNode extends AutoSinkMediaNode<"audio" | "video"> {
868
+ makeCut(request: FrameStoreCutRequest): void;
833
869
  }
834
870
  /**
835
871
  * @public