///
import { PlainMessage } from "@bufbuild/protobuf";
import { Schema as SchemaPB, StreamStatisticsSampling, Subscription, SipEvent_Status, KantarSnapLicenseInformation as KantarSnapLicenseInformationPB, GeminiPart as GeminiPartPB } from "@norskvideo/norsk-api/lib/media_pb";
import { FrameRate, VancPayloadFormat, VancType2AncillaryId } from "../types";
import { AutoSinkMediaNode, MediaClient, MediaNodeState, SinkNodeSettings, SourceMediaNode, SourceMediaNodeEvents, SourceNodeSettings, StreamStatisticsMixin } from "./common";
import { AacProfile, AudioMeasureLevels, AwsCredentials, ChannelLayout, ComposeMissingStreamBehaviour, ComposeHardwareAcceleration, Db, IceServerSettings, LoganH264, LoganHevc, MultiStreamStatistics, NvidiaH264, NvidiaHevc, PixelFormat, QuadraH264, QuadraHevc, AmdU30H264, AmdU30Hevc, AmdMA35DH264, AmdMA35DHevc, Resolution, SampleAspectRatio, SampleRate, SentenceBuildMode, SimpleEasing, StabilizationMode, StreamKey, StreamMetadata, X264Codec, X265Codec, SubscriptionError, DeinterlaceSettings, Scte35SpliceInfoSection, Interval, SampleFormat, VideoStreamMetadata, QuadraAv1, AmdMA35DAv1, QuadraPipelineHints } from "./types";
import { Writable, Readable } from 'stream';
/** @public */
export interface ProcessorMediaNode extends SourceMediaNode, AutoSinkMediaNode {
}
/** @public */
export declare class ProcessorMediaNode {
constructor(client: MediaClient, unregisterNode: (node: MediaNodeState) => void, getGrpcStream: () => (Readable | Writable), subscribeFn: (subscription: Subscription) => Promise, subscribeErrorFn?: (error: SubscriptionError) => void, subscribedStreamsChangedFn?: (streams: StreamMetadata[]) => void);
}
/** @public */
export interface AutoProcessorMediaNode extends SourceMediaNode, AutoSinkMediaNode {
}
/** @public */
export declare class AutoProcessorMediaNode {
constructor(client: MediaClient, _unregisterNode: (node: MediaNodeState) => void, getGrpcStream: () => (Readable | Writable), subscribeFn: (subscription: Subscription) => Promise, subscribeErrorFn?: (error: SubscriptionError) => void, subscribedStreamsChangedFn?: (streams: StreamMetadata[]) => void);
}
/** @public */
export interface ProcessorNodeSettings extends SinkNodeSettings, SourceNodeSettings {
}
/**
* @public
* Settings for the Hard Stream Switch
* see: {@link NorskControl.streamSwitchHard}
* */
export interface StreamSwitchHardSettings extends ProcessorNodeSettings> {
/** The currently active source to display on the output */
activeSource: Pins;
/** the source name to give the output of this switch operation */
outputSource: string;
}
/**
* @public
* see: {@link NorskControl.streamSwitchHard}
*/
export declare class StreamSwitchHardNode extends ProcessorMediaNode {
switchSource(newSource: Pins): void;
}
/**
* @public
* Settings for the Smooth Source Switch
* see {@link NorskControl.streamSwitchSmooth}
* */
export interface StreamSwitchSmoothSettings extends ProcessorNodeSettings> {
/** The presently active source being used to generate output for this node */
activeSource?: Pins;
/** The source name given to the output of this node */
outputSource: string;
/** How many milliseconds to use for the fade operation between two sources */
transitionDurationMs?: number;
/** The constant resolution that all output video will be scaled to */
outputResolution: Resolution;
/** The constant framerate that all output video will be sampled to */
frameRate: FrameRate;
/** The constant samplerate that all output audio will be resampled to */
sampleRate: SampleRate;
/** The sample format of the built outgoing stream (Defaults to FLTP)*/
sampleFormat?: SampleFormat;
/** The constant channel layout that all output audio will be resampled to */
channelLayout: ChannelLayout;
/** Alignment behaviour of the component
* whether to rebase all incoming streams to a common timeline
* Note: This will modify the timestamps, meaning that merging streams not involved in this may result in
* operation may result in sync issues. To avoid this, you can use {@link NorskTransform.streamAlign} instead of relying
* on this component for this behaviour
* Note: This behaviour may be removed in a future release and replaced with something similar
* */
alignment?: "aligned" | "not_aligned";
/** Callback which will be called if a switch request cannot be fulfilled */
onSwitchError?: (message: string, inputPin?: Pins) => void;
/** Callback which will be called a transition has succesfully completed for a requested switch, i.e. the new source
* is now showing.
*
* Note that if additional transitions are triggered when a transition is already in progress, a notification may only be
* given for the last transition to finish.
**/
onTransitionComplete?: (inputPin: Pins) => void;
/**
* Callback to be called when inbound context changes on some input; presence of an
* input means that media has arrived and is ready to switch
* immediately
* @param allStreams - The collection of input contexts received over all input pins
*/
onInboundContextChange?: (allStreams: Map) => Promise;
/**
* Optionally attempt to perform the compose operation on hardware
*/
hardwareAcceleration?: ComposeHardwareAcceleration;
}
export interface StreamSwitchSmoothSwitchOptions {
/** Duration to switch for this transition only (if omitted, the configured default shall be used, to suppress a transition specify this but as 0). */
transitionDurationMs?: number;
}
/**
* @public
* see: {@link NorskControl.streamSwitchSmooth}
*/
export declare class StreamSwitchSmoothNode extends ProcessorMediaNode {
/**
* @public
* The currently active source
*/
get activeSource(): Pins | undefined;
private _activeSource?;
/**
* @public
* Switches the source used for the current output of this node
*/
switchSource(newSource: Pins, options?: StreamSwitchSmoothSwitchOptions): Promise;
}
/**
* @public
* Settings for a Stream Statistics Node
* see: {@link NorskControl.streamStatistics}
*/
export interface StreamStatisticsSettings extends ProcessorNodeSettings, StreamStatisticsMixin {
/**
* Called periodically with the stream stats
* @param stats - The statistics for the stream
* @eventProperty
*/
onStreamStatistics: (stats: MultiStreamStatistics) => void;
/**
* Sampling rates for stream stats, in seconds
*/
statsSampling?: PlainMessage;
}
/**
* @public
* see {@link NorskControl.streamStatistics}.
*/
export declare class StreamStatisticsNode extends AutoProcessorMediaNode<"audio" | "video"> {
}
/**
* @public
* Settings for an AudioMeasureLevelsNode
* see: {@link NorskControl.audioMeasureLevels}
*/
export interface AudioMeasureLevelsSettings extends ProcessorNodeSettings {
/**
* Called with the audio level data
* @param levels - The level data for the audio stream
* @eventProperty
*/
onData: (levels: AudioMeasureLevels) => void;
/** Optionally control the sample frequency */
intervalFrames?: number;
}
/**
* @public
* see: {@link NorskControl.audioMeasureLevels}.
*/
export declare class AudioMeasureLevelsNode extends AutoProcessorMediaNode<"audio"> {
}
/**
* @public
* Recursive definition for defining types
*/
export type Schema = {
type: "string";
description: string;
} | {
type: "number";
description: string;
} | {
type: "boolean";
description: string;
} | {
type: "array";
items: Schema;
description: string;
} | {
type: "object";
properties: Record;
description: string;
};
/**
* @public
* Definition for a parameter in a function call
*/
export type Parameter = {
name: string;
description: string;
type: "string";
} | {
name: string;
description: string;
type: "number";
} | {
name: string;
description: string;
type: "boolean";
} | {
name: string;
description: string;
type: "array";
items: Schema;
} | {
name: string;
description: string;
type: "object";
properties: Record;
};
/**
* @public
* Definition for metadata passed as the first argument to a Gemini function call
*/
export type FunctionCallMetadata = {
frameUtc?: Date;
};
/**
* @public
* Definition for a function call
*/
export type FunctionDeclaration = {
name: string;
description: string;
parameters: Parameter[];
response?: Schema;
function: (metadata: FunctionCallMetadata, ...args: any[]) => any | Promise;
};
export type GeminiTextPart = {
partType: "text";
value: string;
};
export type GeminiBlobPart = {
partType: "blob";
mimeType: string;
base64: string;
};
export type GeminiPart = GeminiTextPart | GeminiBlobPart;
export type GeminiTurn = {
parts: GeminiPart[];
};
export type GeminiServerContent = {
turnComplete: boolean;
interrupted: boolean;
parts: GeminiPart[];
};
export type GeminiVideoLiveApi = {
apiType: "live";
};
export type GeminiVideoSingleShotApi = {
apiType: "singleShot";
historicalContextMs: number;
prompt: string;
};
export type GeminiVideoApi = GeminiVideoLiveApi | GeminiVideoSingleShotApi;
/**
* @public
* Settings for Gemini Video
*/
export interface GeminiVideoSettings {
resolution: Resolution;
frameRate: FrameRate;
videoApi: GeminiVideoApi;
}
/**
* @public
* Settings for a GeminiProcessorNode
* see: {@link NorskControl.geminiProcessor}
*/
export interface GeminiSettings extends ProcessorNodeSettings {
googleApiKey: string;
model: string;
systemInstruction: string;
functions: FunctionDeclaration[];
videoSettings?: GeminiVideoSettings;
infoCb?: (status: "connected" | "setupStarted" | "setupCompleted") => void;
contentCb?: (content: GeminiServerContent) => void;
}
/**
* @public
* see: {@link NorskControl.geminiProcessor}.
*/
export declare class GeminiProcessorNode extends AutoProcessorMediaNode<"audio" | "video"> {
static toSchemaPB(schema: Schema): SchemaPB;
static parameterToSchema(parameter: Parameter): Schema;
static partFromPB(part: GeminiPartPB): GeminiPart;
}
/**
* @public
* Settings for a Stream Timestamp Nudge
* see: {@link NorskTransform.streamTimestampNudge}
* */
export interface StreamTimestampNudgeSettings extends ProcessorNodeSettings {
/** the initial nudge to apply, in milliseconds */
nudge?: number;
}
/**
* @public
* see: {@link NorskTransform.streamTimestampNudge}
*/
export declare class StreamTimestampNudgeNode extends AutoProcessorMediaNode<"audio" | "video"> {
/**
* @public
* Applies a gradual nudge to the stream timestamps by the specified number of milliseconds
* */
nudge(nudge: number): void;
}
/**
* @public
* Settings for a Stream Key Override
* see: {@link NorskTransform.streamKeyOverride}
* */
export interface StreamKeyOverrideSettings extends ProcessorNodeSettings {
/** The stream key that all frames passing through this node will be assigned */
streamKey: StreamKey;
metrics?: "enabled" | "minimal" | "none";
}
/**
* @public
* see: {@link NorskTransform.streamKeyOverride}
*/
export declare class StreamKeyOverrideNode extends AutoProcessorMediaNode<"audio" | "video" | "subtitle"> {
}
/**
* @public
* Settings for a Stream Metadata Override Node
* see: {@link NorskTransform.streamMetadataOverride}
* */
export interface StreamMetadataOverrideSettings extends ProcessorNodeSettings, StreamMetadataOverrideSettingsUpdate {
}
/** @public */
export interface StreamMetadataOverrideSettingsUpdate {
video?: {
/** Override the bitrate metadata of a compressed video stream, or `0` to clear */
bitrate?: number;
};
audio?: {
/** Override the bitrate metadata of a compressed audio stream, or `0` to clear */
bitrate?: number;
/** Override the language metadata of an audio stream, or `""` to clear. RFC 5646 language tag. */
language?: string;
};
subtitles?: {
/** Override the language metadata of a subtitles stream, or `""` to clear. RFC 5646 language tag. */
language?: string;
/** Override the property of whether a subtitles string is the default/primary rendition or not */
default?: boolean;
};
playlist?: {
/** Override the name of a playlist stream, or `""` to clear. Free form text. */
name?: string;
};
}
/**
* @public
* see: {@link NorskTransform.streamMetadataOverride}
*/
export declare class StreamMetadataOverrideNode extends AutoProcessorMediaNode<"audio" | "video" | "subtitle"> {
/**
* @public
* Updates the config used by this metadata override node for all subsequent frames
* @param settings - The new settings
*/
updateConfig(settings: StreamMetadataOverrideSettingsUpdate): void;
}
/**
* @public
* Settings for a Jitter Buffer
* see: {@link NorskTransform.jitterBuffer}
* */
export interface JitterBufferSettings extends ProcessorNodeSettings {
/** Buffer delay in milliseconds */
delayMs: number;
}
/**
* @public
* see: {@link NorskTransform.jitterBuffer}
*/
export declare class JitterBufferNode extends AutoProcessorMediaNode<"audio" | "video" | "subtitle"> {
}
/**
* @public
* Settings for a StreamSync node
* see {@link NorskTransform.streamSync}
* */
export interface StreamSyncSettings extends ProcessorNodeSettings {
}
/**
* @public
* see: {@link NorskTransform.streamSync}
*/
export declare class StreamSyncNode extends AutoProcessorMediaNode<"audio" | "video"> {
}
/**
* @public
* Settings for a StreamAlign node
* This will reset all streams to the same framerates/sample rates
* and align their timestamps so that they completely line up for downstream operations
* see {@link NorskTransform.streamAlign}
* */
export interface StreamAlignSettings extends ProcessorNodeSettings {
/** The normalisd sample rate of the audio output */
sampleRate: SampleRate;
/** The normalised frame rate of the video output */
frameRate: FrameRate;
/** Synchronise audio/video sources aggressively to start at the same timestamp by dropping frames until a video keyframe occurs */
syncAv?: boolean;
}
/**
* @public
* see: {@link NorskTransform.streamAlign}
*/
export declare class StreamAlignNode extends AutoProcessorMediaNode<"audio" | "video"> {
}
/** @public */
export interface StreamConditionSettings extends ProcessorNodeSettings {
}
/** @public */
export interface StreamConditionRequest {
kind: 'in' | 'out' | 'idr_only';
pts?: Interval;
}
/**
* @public
* see: {@link NorskTransform.streamCondition}
*/
export declare class StreamConditionNode extends AutoProcessorMediaNode<"audio" | "video" | "ancillary"> {
/** @public */
condition(request: StreamConditionRequest): void;
}
/** @public */
export interface Scte35MessageEvent extends Scte35SpliceInfoSection {
pts: Interval;
}
/** @public */
export interface Scte35Message extends Scte35SpliceInfoSection {
pts?: Interval;
}
/** @public */
export interface Smpte2038MessageEvent extends Smpte2038Message {
pts: Interval;
}
/** @public */
export interface Smpte2038SendMessage extends Smpte2038Message {
pts?: Interval;
}
/** @public */
export interface Smpte2038Message {
cNotYChannelFlag: boolean;
lineNumber: number;
horizontalOffset: number;
payloadFormat: VancPayloadFormat;
ancillaryId: VancType2AncillaryId;
userData: Uint8Array;
}
/** @public */
export type MetadataFormat = 'klv' | 'id3';
/**
* @public
* A metadata message as carried in a Transport Stream
* */
export interface MetadataMessage {
/** Raw metadata message data */
data: Uint8Array;
/** Metadata service id (if present) */
serviceId: number;
/** Format of the metadata (if known) */
format?: MetadataFormat;
}
/** @public */
export interface MetadataMessageEvent extends MetadataMessage {
/** Timestamp of the message */
pts: Interval;
}
/** @public */
export interface MetadataSendMessage extends MetadataMessage {
/** Timestamp of the message */
pts?: Interval;
}
/**
* @public
* Settings for an Ancillary node
* see {@link NorskTransform.ancillary}
*/
export interface AncillarySettings extends ProcessorNodeSettings {
onScte35?: (stream: StreamKey, message: Scte35MessageEvent) => void;
onSmpte2038?: (stream: StreamKey, message: Smpte2038Message) => void;
onMetadata?: (stream: StreamKey, message: MetadataMessageEvent) => void;
/**
* Called when a reference clock is available, i.e. a message with a time of "now" can be generated.
*
* This means data arriving on a video/audio stream the ancillary node is subscribed to - such a subscription is required
* for "now" timestamps but not for explicitly specified timestamp values derived from input ancillary messages or other nodes.
*/
onReferenceClockAvailable?: () => void;
}
/**
* @public
* see: {@link NorskTransform.ancillary}
*/
export declare class AncillaryNode extends AutoProcessorMediaNode<"ancillary"> {
/** Send a SCTE-35 message.
*
* The pts may be specified, in which case it should correspond to the same program
* (e.g. obtained from a receieved SCTE-35 message or other timestamped message from that program), or it may be
* omitted to send "now". If omitting the pts, the node must subscribe to an audio or video stream from the target
* program in order to fix the latest timestamp to consider "now".
*/
sendScte35(key: StreamKey, info: Scte35Message): void;
/** Send a metadata message (eg ID3 timed metadata, or KLV)
*
* The pts may be specified, in which case it should correspond to the same program
* (e.g. obtained from a receieved message from that program), or it may be
* omitted to send "now". If omitting the pts, the node must subscribe to an audio or video stream from the target
* program in order to fix the latest timestamp to consider "now".
*/
sendMetadata(key: StreamKey, info: MetadataSendMessage): void;
}
/**
* @public
* Settings for a MetadataCombineNode, see {@link NorskTransform.metadataCombine}
* */
export interface MetadataCombineSettings extends ProcessorNodeSettings {
outputStreamKey: StreamKey;
maxSyncDelta?: number;
}
/**
* @public
* see: {@link NorskTransform.metadataCombine}
*/
export declare class MetadataCombineMode extends AutoProcessorMediaNode<"ancillary"> {
}
/**
* @public
* Settings for an Opus encode
* see: {@link NorskTransform.audioEncode}
* */
export interface OpusSettings {
kind: "opus";
}
/**
* @public
* Settings for an AAC encode
* see: {@link NorskTransform.audioEncode}
*/
export interface AacSettings {
kind: "aac";
/** The output sample rate of this AAC encode */
sampleRate: SampleRate;
/** The AAC profile of this AAC encode */
profile: AacProfile;
}
/**
* @public
* Settings for an audio encode
* see: {@link NorskTransform.audioEncode}
* */
export interface AudioEncodeSettings extends ProcessorNodeSettings {
/**
* The channel layout of this encode
* Note: If the channel layout doesn't match then it will be automatically converted
* to gain greater control over this process, see {@link NorskTransform.audioMix} and {@link NorskTransform.audioMixMatrix}
* */
channelLayout: ChannelLayout;
/** The target bitrate of this encode */
bitrate: number;
/** The name given to the rendition portion of the stream key assigned to this node's output */
outputRenditionName: string;
/** What codec to (re) encode the audio to */
codec: OpusSettings | AacSettings;
}
/**
* @public
* see: {@link NorskTransform.audioEncode}
*/
export declare class AudioEncodeNode extends AutoProcessorMediaNode<"audio"> {
}
/**
* @public
* A rectangle used for describing a subset of an image
* */
export interface OffsetRect {
/** The leftmost coordinate of the rect, where 0,0 is top left */
x: number;
/** The topmost coordinate of the rect, where 0,0 is top left */
y: number;
/** the width of this rectangle */
width: number;
/** the height of this rectangle */
height: number;
}
export interface ComposePart {
/** Input pin for this source */
pin: Pins;
/**
* Z-index to determine ordering by which the sources are overlaid
* (higher layers appear on top)
*/
zIndex: number;
/**
* Opacity multiplier of this overlay (where 0.0 is fully transparent and 1.0
* is fully opaque)
*/
opacity: number;
/** Optionally identify the part to enable transitions */
id?: string;
/**
* Optionally specify a transition for this part. A transition is applied only
* if the part is specified in both the existing and the current/new
* configuration, identified by having the same id specified, and a transition
* is specified for the new configuration.
*/
transition?: PartTransition;
/**
* A callback that produces a compose operation, specifying in exact pixels
* a) The source rect from the source video to select
* b) The dest rect within the output video to render to
*/
compose: (partStream: VideoStreamMetadata, settings: VideoComposeSettings) => ComposeOperation;
}
/**
* @public
* The base OnlineLicense interface for the {@link NorskKantarEmbedder.kantarEmbedder}
*/
export interface KantarSnapOnlineLicenseBase {
/**
* The license type - must be "online"
*/
type: "online";
/**
* Your login to the Kantar licensing server
*/
login: string;
/**
* The password corresponding to your login
*/
password: string;
/**
* The Kantar licensing server address. Defaults to "licenseofe.kantarmedia.com". For
* testing, you likely want to use "licenseofe-integration.kantarmedia.fr".
*/
server?: string;
/**
* The port that the licensing server listens on. Defaults to 443.
*/
port?: number;
}
/**
* @public
* The base OfflineLicense interface for the {@link NorskKantarEmbedder.kantarEmbedder}
*/
export interface KantarSnapOfflineLicenseBase {
/**
* The license type - must be "offline"
*/
type: "offline";
/**
* The path to your license file; this is from the context of the Norsk media container.
*/
kantarLicensePath: string;
/**
* The path to your audience license file; this is from the context of the Norsk media container.
*/
audienceLicensePath: string;
}
/**
* @public
* OnlineLicense definition for the {@link NorskKantarEmbedder.kantarEmbedder}
*/
export interface KantarSnapOnlineLicense extends KantarSnapOnlineLicenseBase {
/**
* The name of the license your wish to use
*/
licenseName: string;
/**
* A json string containing the name of the channel you wish to use, plus any other information
* as required by Kantar. e.g.:
* "\{\"channel_name\":\"channel1\"\}"
*/
jsonMetadata: string;
}
/**
* @public
* OfflineLicense definition for the {@link NorskKantarEmbedder.kantarEmbedder}
*/
export interface KantarSnapOfflineLicense extends KantarSnapOfflineLicenseBase {
/**
* The channel name you wish to use
*/
channelName: string;
}
/**
* @public
* Event raised by the Kantar Snap Embedder; see {@link NorskKantarEmbedder.kantarEmbedder}
*/
export interface KantarSnapSnapEvent {
/**
* The event severity
*/
eventType: "info" | "warning" | "error";
/**
* The Kantar event code. Refer to Kantar documentation or support to intepret this number.
*/
code: number;
/**
* A human-readable description of the event
*/
message: string;
}
/**
* @public
* Information about a channel within a license
*/
export interface KantarSnapChannelInfo {
channelName: string;
channelId: bigint;
}
/**
* @public
* License information, as reported by the Kantar Snap Embedder; see {@link NorskKantarEmbedder.kantarEmbedder}
*/
export interface KantarSnapLicenseInformation {
/**
* The days remaining until this license must be refreshed. -1 indicates a perpetual license.
*/
remainingDays: number;
/**
* List of channels available with this license
*/
channelInfos: KantarSnapChannelInfo[];
}
/**
* @public
* Online License information, as reported by the Kantar Snap Embedder; see {@link NorskKantarEmbedder.kantarEmbedder}
*/
export interface KantarSnapOnlineLicenseInformation {
/**
* The name of the license
*/
name: string;
/**
* Information about the license
*/
information: KantarSnapLicenseInformation;
}
/**
* @public
* Settings for an Kantar Audio Watermark Embedder node
* see: {@link NorskKantarEmbedder.kantarEmbedder}
* */
export interface KantarSnapSettings extends ProcessorNodeSettings {
/**
* The license settings
*/
license: KantarSnapOnlineLicense | KantarSnapOfflineLicense;
/**
* Event fired at startup, providing information about the current license
*/
onLicenseInformation?: (info: KantarSnapLicenseInformation) => void;
/**
* Event fired whenever the Kantar Snap Embedder raises an event
*/
onSnapEvent?: (event: KantarSnapSnapEvent) => void;
/**
* Event first whenever a timecode resync occurs
*/
onTimecodeResync?: () => void;
}
/**
* @public
* Kantar version information
* */
export interface KantarVersion {
/**
* The version of the norsk-to-kantar integration library
*/
norskIntegrationVersion: string;
/**
* The version of the Kantar SDK
*/
kantarSdkVersion: string;
}
/**
* @public
* see: {@link NorskKantarEmbedder.kantarEmbedder}
* */
export declare class KantarSnapNode extends AutoProcessorMediaNode<"audio"> {
static queryOnlineLicense(settings: KantarSnapOnlineLicenseBase, client: MediaClient): Promise;
static queryOfflineLicense(settings: KantarSnapOfflineLicenseBase, client: MediaClient): Promise;
static queryVersion(client: MediaClient): Promise;
static licenseInfoFromPB(licenseInfo: KantarSnapLicenseInformationPB): KantarSnapLicenseInformation;
/** @public
* If the Kantar license needs updating, for example because it is due to expire, then call this method with the new license details. Norsk will perform the license update with no interruption to the audio stream.
*/
updateLicense(license: KantarSnapOnlineLicense | KantarSnapOfflineLicense): void;
}
/**
* The return result of a compose callback, directing which pixels to place where
*/
export type ComposeOperation = {
/**
* The area within the source picture to include. This may be the full picture
* or cropped, and will be rescaled if necessary.
*/
sourceRect: OffsetRect;
/**
* The area within the destination picture to place this part of the composition.
*/
destRect: OffsetRect;
};
/**
* Helpers for generating standard compose results
*/
export declare const VideoComposeDefaults: {
/**
* Takes the whole input part and renders it over the whole output video, scaling it as required to fit
* and entirely ignoring aspect ratio in doing so
*/
fullscreen: () => (partStream: VideoStreamMetadata, settings: VideoComposeSettings) => ComposeOperation;
fixed: ({ sourceRect, destRect, referenceResolution }: {
sourceRect: OffsetRect;
destRect: OffsetRect;
referenceResolution: Resolution;
}) => (partStream: VideoStreamMetadata, settings: VideoComposeSettings) => ComposeOperation;
/**
* Given a set of percentage based rects
* a) Take the source part and crop using the source percentages specified
* b) Render it onto the output video using the output percentages specified
*/
percentage: ({ sourceRect, destRect }: {
sourceRect: OffsetRect;
destRect: OffsetRect;
}) => (partStream: VideoStreamMetadata, settings: VideoComposeSettings) => ComposeOperation;
};
/** @public
* A transition for a video composition part.
*
* A transition interpolates the source_rect, dest_rect, and opacity properties
* over the specified duration according to the specified easing function.
*
* As a special case, if a transition is specified and the input pin of the part
* changes, an opacity fade from one to the other will occur.
*/
export interface PartTransition {
/** Duration for the transition */
durationMs: number;
/**
* Easing function to apply to the transition. If not specified will be
* linear.
*/
easing?: SimpleEasing;
}
/**
* Settings for a VideoCompose node
*/
export interface VideoComposeSettings extends ProcessorNodeSettings> {
/**
* Required. Pin name of the reference stream. This is the video stream
* which defines the output frame timing, which will typically be part of the
* composition, e.g. the main picture in the case of a simple
* overlay/picture-in-picture, or the top left quadrant of a 4-way split
* screen.
*/
referenceStream: Pins;
/** The parts (images/overlays) to include in the composition
The functions provided here will be invoked when source contexts arrive
so that pixel-based configuration can be generated
see @see VideoComposeDefaults for helpers
*/
parts: readonly (ComposePart)[];
/** The resolution of the output video */
outputResolution: Resolution;
/**
* Output pixel format to use. If not specified, this will be chosen
* automatically based on the sources present in the initial composition
*/
outputPixelFormat?: PixelFormat;
/**
* Behaviour in the case of a missing stream used in an active composition
* part. Note that this does not apply to the reference stream, but to every
* part which does not use the reference stream, whether at startup or on
* context change.
*
* Missing means not present in the context or never having sent a frame.
*/
missingStreamBehaviour?: ComposeMissingStreamBehaviour;
/**
* Optionally attempt to perform the compose operation on hardware
*/
hardwareAcceleration?: ComposeHardwareAcceleration;
/**
* Called when the transitions specified in the last config update have
* completed (in the case of multiple parts with specified transitions of
* different duration, this means that the last remaining transitions have
* completed
*/
onTransitionComplete?: () => void;
}
/**
* @public
* An update operation for a VideoCompose operation
* see: {@link VideoComposeNode.updateConfig}
* */
export interface VideoComposeSettingsUpdate {
/** Update the parts (images/overlays) to include in the composition */
parts: readonly ComposePart[];
}
/**
* @public
* see: {@link NorskTransform.videoCompose}
*/
export declare class VideoComposeNode extends ProcessorMediaNode {
lastContext: Map;
/**
* @public
* Updates the config used for a video compose operation
* If transitions are specified, animations will be provided, otherwise
* the change will be immediate
*
* Note: This is not a 'cheap' operation and care should be taken not to
* do this too often (more than once a second for example!)
*/
updateConfig(settings: VideoComposeSettingsUpdate): void;
doConfigUpdate(): void;
}
/**
* @public
* The settings for a single source within an AudioMix operation
* see: {@link NorskTransform.audioMix}
* */
export interface AudioMixSource {
/** The name of the InputPin for this source */
pin: Pins;
/** A vector of gains for this source, one for each channel */
channelGains?: readonly Gain[];
}
/**
* @public
* The settings for an AudioMix operation
* see: {@link NorskTransform.audioMix}
* */
export interface AudioMixSettings extends ProcessorNodeSettings> {
/** The audio sources to mix */
sources: readonly AudioMixSource[];
/** The source name to use for the output stream */
outputSource: string;
/** The channel layout that the mixer runs at
* all audio streams will be normalised to this value and therefore
* this will be the output channel layout of this node */
channelLayout: ChannelLayout;
/** The sample rate that the mixer runs at
* all audio streams will be normalised to this value and therefore
* this will be the output sample rate of this node */
sampleRate?: SampleRate;
}
/**
* @public
* An update operation for an AudioMix node
* see: {@link AudioMixNode.updateConfig}
* */
export interface AudioMixSettingsUpdate {
/** The audio sources to mix along with their potentially new gain values */
sources: readonly AudioMixSource[];
}
/**
* @public
* see: {@link NorskTransform.audioMix}
*/
export declare class AudioMixNode extends ProcessorMediaNode {
/**
* @public
* Updates the config of this AudioMix for all subsequent frames
* this allows the user to change the levels and sources in the outgoing mix
* dynamically as the stream progresses
* @param settings - The updated settings
*/
updateConfig(settings: AudioMixSettingsUpdate): void;
}
/**
* @public
* A relative change in decibels, expressing a power ratio.
*
* A value of 0dB means no change, positive values mean an increase in power, and negative values mean a decrease in power.
*/
export type Gain = Db;
/**
* @public
* Settings for the Audio Mix Matrix Node
* see: {@link NorskTransform.audioMixMatrix}
* */
export interface AudioMixMatrixSettings extends ProcessorNodeSettings {
/** The NxM matrix of gains from N input channels to M output channels */
channelGains: readonly Gain[][];
/** The desired output channel layout, such as "5.1" */
outputChannelLayout: ChannelLayout;
}
/**
* @public
* Config update for the {@link AudioMixMatrixNode}.
* Call {@link AudioMixMatrixNode.updateConfig} for updating the config.
*/
export interface AudioMixMatrixSettingsUpdate {
/** The NxM updated matrix of gains from N input channels to M output channels */
channelGains: readonly Gain[][];
}
/**
* @public
* see: {@link NorskTransform.audioMixMatrix}
*/
export declare class AudioMixMatrixNode extends AutoProcessorMediaNode<"audio"> {
/**
* @public
* Updates the config of this AudioMixMatrix node for all subsequent frames
* this allows the user to change the gains in the outgoing mix
* dynamically as the stream progresses
* @param settings - The updated settings
*/
updateConfig(settings: AudioMixMatrixSettingsUpdate): void;
}
/**
* @public
* Settings for an Audio Gain node
* see: {@link NorskTransform.audioGain}
* */
export interface AudioGainSettings extends ProcessorNodeSettings {
/** A vector of gains for this source, one for each channel */
channelGains: readonly Gain[];
onInputChanged?: (metadata?: StreamMetadata) => void;
}
/**
* @public
* An update operation for an Audio Gain node
* see: {@link AudioGainNode.updateConfig}
* */
export interface AudioGainSettingsUpdate {
/** A vector of gains for this source, one for each channel */
channelGains?: readonly Gain[];
}
/**
* @public
* see: {@link NorskTransform.audioGain}
*/
export declare class AudioGainNode extends AutoProcessorMediaNode<"audio"> {
/**
* @public
* Updates the config of this AudioGain node for all subsequent frames
* this allows the user to change the gains in the outgoing stream
* dynamically as the stream progresses
* @param settings - The updated settings
*/
updateConfig(settings: AudioGainSettingsUpdate): void;
}
/**
* @public
* Settings for an Audio Split Multichannel node
* see: {@link NorskTransform.audioSplitMultichannel}
* */
export interface AudioSplitMultichannelSettings extends ProcessorNodeSettings {
/**
* The output stream key of the first channel
* subsequent channels will have streamId incremented by N
*/
outputStreamKey: StreamKey;
metrics?: "enabled" | "minimal" | "none";
}
/**
* @public
* see: {@link NorskTransform.audioSplitMultichannel}
*/
export declare class AudioSplitMultichannelNode extends AutoProcessorMediaNode<"audio"> {
}
/**
* @public
* Settings for an Audio Build Multichannel Node
* see: {@link NorskTransform.audioBuildMultichannel}
* */
export interface AudioBuildMultichannelSettings extends ProcessorNodeSettings {
/** The channel layout of the built outgoing stream */
channelLayout: ChannelLayout;
/** The sample rate of the built outgoing stream */
sampleRate: SampleRate;
/** The sample format of the built outgoing stream (Defaults to FLTP)*/
sampleFormat?: SampleFormat;
/**
* Stream keys specifying the source for each channel, where the order is
* significant. The streams must all have the same sample format and sample
* rate.
*/
channelList: readonly StreamKey[];
/**
* Callback invoked when the inbound context changes
* a new channel list can be returned here that overrides the initial configuration
* and allows the channel order to be changed at runtime
*/
onInputChanged?: (keys: StreamKey[]) => StreamKey[] | undefined;
/** The stream key to use for the outging stream*/
outputStreamKey: StreamKey;
metrics?: "enabled" | "minimal" | "none";
}
/**
* @public
* see: {@link NorskTransform.audioBuildMultichannel}
*/
export declare class AudioBuildMultichannelNode extends AutoProcessorMediaNode<"audio"> {
}
/**
* @public
* Settings for an Audio Transcribe operation using AWS
* see: {@link NorskTransform.audioTranscribeAws}
* */
export interface AudioTranscribeAwsSettings extends ProcessorNodeSettings {
/** Region for the transcribe endpoint */
awsRegion: string;
/** the stream id to allocate to the outgoing stream*/
outputStreamId: number;
/** the language that we want to transcribe (also put in the outgoing metadata) */
language: string;
/** The mode to be used for building sentences */
sentenceBuildMode: SentenceBuildMode;
/** The mode to be used for stabilising sentences */
sentenceStabilizationMode: StabilizationMode;
/** The AWS credentials to use for this operation
* If not supplied, the standard environment variables will be used if present, or EC2 role credentials (IMDSv1)
* */
awsCredentials?: AwsCredentials;
}
/**
* @public
* see: {@link NorskTransform.audioTranscribeAws}
*/
export declare class AudioTranscribeAwsNode extends AutoProcessorMediaNode<"audio"> {
}
/**
* @public
* Settings for an Audio Transcribe operation using AWS
* see: {@link NorskTransform.subtitleTranslateAws}
* */
export interface SubtitleTranslateAwsSettings extends ProcessorNodeSettings {
/** Source language code/tag, e.g. de or fr-CA (omit to use the source subtitle language / AWS automatic detection) */
sourceLanguage?: string;
/** Target language code/tag, e.g. en or es-MX */
targetLanguage: string;
/** Enable brevity option */
brevity?: boolean;
/** Enable profanity masking */
maskProfanity?: boolean;
}
/**
* @public
* see: {@link NorskTransform.subtitleTranslateAws}
*/
export declare class SubtitleTranslateAwsNode extends AutoProcessorMediaNode<"audio"> {
}
/**
* @public
* CTA-608 format (note this may be embedded in 708 according to output container)
*/
export type Cta608Format = {
kind: '608';
/** Caption style (default: selected according to source) */
style?: 'pop-on' | 'roll-up';
/** The total/maximum number of lines to use for captioning */
lines?: number;
};
/**
* @public
* CTA-708 format (this means native 708, not the embedding of 608 in 708)
*/
export type Cta708Format = {
kind: '708';
};
/**
* @public
* WebVTT format
*/
export type WebVttFormat = {
kind: 'webvtt';
/** Maximum length of any line in the cue in characters */
maximumLineLength?: number;
/** Minimum length of the overall cue in characters */
minimumCueLength?: number;
/** Maximum number of lines in a cue.
*
* Consider using a value of 1 and a longer max line length and allowing the player to break lines: per the WebVTT standard
* "In general, therefore, authors are encouraged to write cues all on one line except when a line break is definitely necessary."
* However if the player does not do this adequately, using the actual max line length desired and more lines, hard line breaks
* will be inserted. Note a maximum subtitle length of two lines is recommended (eg BBC guidance)
*/
maximumNumLines?: number;
/** Maximum gap between fragments before breaking into a separate cue. By default some unspecified gap value will be used */
maximumGapMs?: number;
/** Maximum duration of the cue, if the cue duration would be greater than this it will be split into a separate cue. By default some unspecified duration value will be used */
maximumDurationMs?: number;
};
/**
* @public
* The format to convert subtitles to
* */
export type SubtitleConvertFormat = Cta608Format | Cta708Format | WebVttFormat;
/**
* @public
* Settings for an Subtitle Convert operation
* see: {@link NorskTransform.subtitleTranslateAws}
* */
export interface SubtitleConvertSettings extends ProcessorNodeSettings {
format: SubtitleConvertFormat;
/** For conversion from transcribed sources containing partial and complete transcriptions, filter to only include the transcription
* from a fully transcribed section/utterance. Note this may be multiple sentences and span up to 30s duration or beyond, making this
* generally an option for non-live flows
*/
onlyComplete?: boolean;
}
/**
* @public
* see: {@link NorskTransform.subtitleConvert}
*/
export declare class SubtitleConvertNode extends AutoProcessorMediaNode<"subtitle"> {
}
/**
* @public
* Settings for an audio transcribe/translate operation using Azure Speech Service
* see: {@link NorskTransform.audioTranscribeAzure}
* */
export interface AudioTranscribeAzureSettings extends ProcessorNodeSettings {
outputStreamId: number;
/** The source language to recognise - an IETF BCP 47 language tag, eg en-US, en-GB, de-DE. Supported languages are
* found at https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=stt
*/
sourceLanguage: string;
/** The target output languages for translation - technically a BCP 47 language tag but but in most cases omitting region, e.g. en, de, zh-Hant.
* Leave this field absent/empty to use the transcription service without
* translation, while if any target languages are present the translation service will be used even if this is the same as the
* source language.
*/
targetLanguages?: string[];
/** Key for the Azure Speech Service endpoint */
azureKey: string;
/** Region for the Azure Speech Service endpoint */
azureRegion: string;
/** Enable dictation mode (recognise dictated punctuation etc rather than transcribing the audio verbatim) */
dictation?: boolean;
/** Profanity behaviour (whether to mask or remove profanity) */
profanity?: 'masked' | 'removed' | 'raw';
}
/**
* @public
* see: {@link NorskTransform.audioTranscribeAws}
*/
export declare class AudioTranscribeAzureNode extends AutoProcessorMediaNode<"audio"> {
}
/**
* @public
* Settings for an Audio Transcribe operation using Whisper sdk (whisper-cpp)
* see: {@link NorskTransform.audioTranscribeWhisper}
* */
export interface AudioTranscribeWhisperSettings extends ProcessorNodeSettings {
/** Stream ID of the output subtitles */
outputStreamId: number;
/** The duration of audio that is accumulated before performing one transcription step. Decreasing this
* value will decrease latency but also decrease performance. Visualiser metrics are available to monitor the
* duration of each "step" operation, if this is not clearly faster than the audio duration real-time output will not be
* attained and the workflow will back up.
*
* Default 3000ms.
*/
stepMs?: number;
/** Duration of audio to keep when clearing the buffer to allow for partial-word recognition. Default 400ms */
keepMs?: number;
/** Max tokens per segment */
maxTokens?: number;
noFallback?: boolean;
/** Number of threads to use. Note using a large number of threads rarely improves performance */
numThreads?: number;
/**
* Use GPU if available. In the cases where GPU is available, it may not necessarily increase performance, but instead opt
* to move load from CPU to GPU.
*/
useGpu?: boolean;
/**
* Language setting for the Whisper model. Leave unset to auto-detect (with a multi-language model)
*/
language?: string;
/**
* The file name of the GGML-format whisper model.
*
* Information: https://github.com/ggerganov/whisper.cpp/blob/master/models/README.md
*
* Model downloads: https://huggingface.co/ggerganov/whisper.cpp/tree/main
*/
model: string;
/**
* Whether to translate a non-English input to English, or leave the foreign-language transcription in the source language.
*/
translate?: boolean;
/**
* Enable tiny-diarize if supported in the given model
*/
tinyDiarize?: boolean;
/**
* Initial prompt to prime the model - this is in addition to prompting based on past transcription history.
*/
initialPrompt?: string;
/**
* Whether to supply a prompt consisting of the tokens recognised in the previous chunk. By default it is not supplied, relying only
* on the overlap of transcription chunks to resolve partial words occurring at the start/end of a chunk.
*/
contextPrompt?: boolean;
/**
* Whether to suppress non-speech tokens
*/
suppressNonSpeechTokens?: boolean;
/** Greedy (default) or beam sampling strategy */
samplingStrategy?: WhisperSamplingStrategy;
initialTemperature?: number;
temperatureIncrement?: number;
entropyThreshold?: number;
logProbThreshold?: number;
noSpeechThreshold?: number;
}
type WhisperSamplingStrategy = {
strategy: 'greedy';
bestOf?: number;
} | {
strategy: "beam_search";
beam_size?: number;
};
/**
* @public
* see: {@link NorskTransform.audioTranscribeWhisper}
*/
export declare class AudioTranscribeWhisperNode extends AutoProcessorMediaNode<"audio"> {
}
/**
* @public
* A single rung in a video encode ladder
* see: {@link NorskTransform.videoEncode}
* */
export interface VideoEncodeRung {
/** The name of this rung, this should be unique across the ladder
* and will end up in the renditionName of the outgoing StreamKey
*/
name: string;
/** The width of the outgoing video resolution */
width: number;
/** The height of the outgoing video resolution */
height: number;
/**
* Optionally change the frameRate for this rendition
* This can be useful if the input is 50FPS for example and some
* lower rungs need to be 25fps
*
* Note: If you wish to apply the same frame rate across all rungs, it is
* more efficient to use a single {@link VideoTransformNode} before the ladder
* created with {@link NorskTransform.videoTransform} and leave this value undefined
* */
frameRate?: FrameRate;
/**
* Specifies the input video's Sample Aspect Ratio (SAR) to be used by the
* encoder in width:height
*/
sar?: SampleAspectRatio;
/**
* The codec (and detailed configuration) to use for the encoding operation.
*
* Note: Nvidia, Logan/Quadra, AmdU30, AmdMA35D require the appropriate hardware to be set up and
* made available to Norsk
*
* A ladder can use several different codecs across its various rungs and the
* VideoEncode node will attempt to build a pipeline that uses the hardware efficently
*/
codec: X264Codec | X265Codec | NvidiaH264 | NvidiaHevc | LoganH264 | LoganHevc | QuadraH264 | QuadraHevc | QuadraAv1 | AmdU30H264 | AmdU30Hevc | AmdMA35DH264 | AmdMA35DHevc | AmdMA35DAv1;
/**
* Extra options for influencing how the ladder gets constructed and what algorithms get used for certain operations
*/
pipelineHints?: QuadraPipelineHints;
}
/**
* @public
* Settings for a VideoEncode operation
* see: {@link NorskTransform.videoEncode}
* */
export interface VideoEncodeSettings extends ProcessorNodeSettings {
rungs: readonly VideoEncodeRung[];
fillGaps?: boolean;
}
/**
* @public
* see: {@link NorskTransform.videoEncode}
*/
export declare class VideoEncodeNode extends AutoProcessorMediaNode<"video"> {
}
/**
* @public
* Settings for a VideoDecode operation
* see: {@link NorskTransform.videoDecode}
* */
export interface VideoDecodeSettings extends ProcessorNodeSettings {
decoder: 'software' | 'nvidia' | 'quadra' | 'logan' | 'amdU30' | 'amdMA35D';
}
/**
* @public
* see: {@link NorskTransform.videoDecode}
*/
export declare class VideoDecodeNode extends AutoProcessorMediaNode<"video"> {
}
/**
* @public
* Settings for a Video Transform node
* see: {@link NorskTransform.videoTransform}
* */
export interface VideoTransformSettings extends ProcessorNodeSettings {
/** An optional resolution to rescale this single stream to */
resolution?: Resolution;
/** An optional framerate to resample this single stream to */
frameRate?: FrameRate;
/** An optional de-interlace algorithm to apply on this stream */
deinterlace?: DeinterlaceSettings;
/** An optional pixel format for output - NB: This only has any effect with in-memory software frames
It is mostly useful if you have a high bpp pixelFormat (for example yuv422p or yuv444p) and want to encode
yuv420p with x264
**/
pixelFormat?: PixelFormat;
/** An optional SAR to set on the outgoing stream
* Note: You can set this and only this if the SAR on your incoming stream is incorrect
* for example (An often-seen problem with sources)
* */
sar?: SampleAspectRatio;
}
/**
* @public
* see: {@link NorskTransform.videoTransform}
*/
export declare class VideoTransformNode extends AutoProcessorMediaNode<"video"> {
}
/**
* @public
* Randomly drop frames on a stream
* - 0.0 means don't drop any frames
* - 1.0 means drop every single frame
* */
export interface DropRandom {
kind: "random";
percentage: number;
start?: number;
end?: number;
}
/**
* @public
* Drop every N frames from an incoming video stream
* */
export interface DropEvery {
kind: "every";
every: number;
}
/**
* @public
* Drop the first N frames from an incoming video stream
* */
export interface DropStart {
kind: "start";
start: number;
}
/**
@public
* Drop a number of frames after a certain N frames have already been accepted
*/
export interface DropAfter {
kind: "drop_after";
start: number;
count: number;
}
/**
* @public
* The settings for a Chaos Monkey
* see: {@link NorskTransform.streamChaosMonkey}
* */
export interface StreamChaosMonkeySettings extends ProcessorNodeSettings {
/** Optional configuration to drop frames from a stream
* leaving this undefined means don't drop any frames
* */
frameDrop?: DropRandom | DropEvery | DropStart | DropAfter;
/**
* Introduce random jitter
*/
jitterMs?: number;
/**
Periodically output a null context and start dropping frames for a specified interval
NB: This will automatically reset should a new context arrive while dropping frames
*/
nullContexts?: {
frequency: number;
duration: number;
};
}
/**
* @public
* see: {@link NorskTransform.streamChaosMonkey}
*/
export declare class StreamChaosMonkeyNode extends AutoProcessorMediaNode<"audio" | "video" | "subtitle"> {
}
/**
* @public
* Settings for a WebRTC browser session
* see: {@link NorskDuplex.webRtcBrowser}
* */
export interface WebRTCBrowserSettings extends ProcessorNodeSettings, StreamStatisticsMixin {
/** List of ice servers to use as part of session negotiation */
iceServers?: IceServerSettings[];
/** Internal addresses for the ice servers (defaults to iceServers) */
reportedIceServers?: IceServerSettings[];
/**
* List of IPs to advertise as your host address - useful e.g. when on a cloud server
* so that the public rather than private IP is used.
*/
hostIps?: string[];
/**
* Similar to hostIps, but a list of server reflexive candidates so that ICE negotiations can be
* sped up
*/
serverReflexiveIps?: string[];
/** Jitter buffer delay in milliseconds */
bufferDelayMs?: number;
}
/**
* @public
* see: {@link NorskDuplex.webRtcBrowser}
*/
export declare class WebRTCBrowserNode extends AutoProcessorMediaNode<"audio" | "video"> {
/** @public The URL of the local player */
playerUrl: string;
}
/**
* @public
* Settings for a SIP session
*/
export interface SipSettings extends ProcessorNodeSettings, StreamStatisticsMixin {
sourceName: string;
bufferDelayMs?: number;
account: SipAccountSettings;
publicAddr?: string;
call: SipCallSettings;
onStatus?: (status: SipEvent_Status) => void;
onConnectionStats?: (stats: SipConnectionStatistics) => void;
}
export interface SipAccountSettings {
id: string;
credentials: SipAccountCredentials;
regUri?: string;
}
export interface SipAccountCredentials {
realm: string;
username: string;
credential: SipAccountCredential;
}
export type SipAccountCredential = {
type: "plain";
password: string;
} | {
type: "digest";
digest: string;
};
export interface SipCallSettings {
address: string;
}
export interface SipConnectionStatistics {
send: SipStreamStatistics;
receive: SipStreamStatistics;
}
export interface SipStreamStatistics {
numBytes: number;
numPackets: number;
}
/**
* @public
* see: {@link NorskDuplex.sip}
*/
export declare class SipNode extends AutoProcessorMediaNode<"audio"> {
/** @public
*
* Send a sequence of DTMF digits, via RFC2833 (if supported by the peer)
*/
sendDtmf(digits: string): void;
}
/**
* @public
* Methods that allow you to both ingest and egest media from your application
* at the same time
*/
export interface NorskDuplex {
/**
* Playback audio/video via webrtc to a browser, and accept audio/video input from a browser.
* The browser client must conform to a custom protocol as implemented in the hosted test page.
* (Available from {@link WebRTCBrowserNode.playerUrl}
* For general WebRTC ingest prefer the WHIP input node, and for egest to a downstream media server
* use the WHIP output node. For browser egest (e.g. stream preview) use the WHEP output node.
* @param settings - Options for the webrtc node
*/
webRtcBrowser(settings: WebRTCBrowserSettings): Promise;
sip(settings: SipSettings): Promise;
}
/**
* @public
* Methods that allow you to embed audio watermarks into your media streams
*/
export interface NorskKantarEmbedder {
/**
* Embeds audio watermarks into the audio stream, using the Kantar Snap Live Embedder.
*
* @remarks
* Norsk supports both online and offline licensing models. In order to get a watermarking
* embedding license, please contact Kantar support at https://www.kantarmedia.com/watermarkinghelpdesk
* with following information:
*
* * Product name and version
*
* * Customer name
*
* * Country
*
* * If different, country of broadcast
*
* * Channel(s) to be watermarked
*
* * Customer internal name for the hardware platform
*
* * AuthorisationCode for each hardware or login contact for online solution.
*
* Once you have obtained the appropriate Kantar license, you can configure this through
* the license field in the settings, providing either an {@link KantarSnapOnlineLicense} or
* an {@link KantarSnapOfflineLicense}. On startup, the {@link KantarSnapSettings.onLicenseInformation} callback
* is called, providing information about your license.
*
* Events from the Kantar embedder are raised through the {@link KantarSnapSettings.onLicenseInformation} callback,
* which you can use to log in your own application's event logs. Norsk also logs this information to the default Norsk
* log files.
*
* Norsk automatically handles synchronisation between the Kantar embedding process and the
* local system time. It performs a resync every 12 hours, and any time that a jump in the
* system clock occurs of more than 10 seconds. This is reported via the {@link KantarSnapSettings.onTimecodeResync} event.
*
* Note that when active, the watermarking processing will introduce a constant audio delay of 2560 audio
* samples, which is 53ms at 48kHz; Norsk will ensure that all related media streams (e.g.
* video) are kept in sync.
*
* Obviously the audio watermark is only applied to streams that it is subscribed to. If for some reason your application
* needs to close the watermarking node, or drop the subscriptions to the source streams to some reason, you should
* ensure that this is done when off-air.
*
* Obviously the audio watermark is only applied to streams that it is subscribed to. If for some reason your application
* needs to close the watermarking node, or drop the subscriptions to the source streams to some reason, you should
* ensure that this is done when off-air.
*
*/
kantarEmbedder(settings: KantarSnapSettings): Promise;
/**
* This method allows you to query the channels available in an offline license
*/
queryKantarOfflineLicense(settings: KantarSnapOfflineLicenseBase): Promise;
/**
* This method allows you to query licenses and the channels available in each license with your login to the Kantar licensing server.
*/
queryKantarOnlineLicense(settings: KantarSnapOnlineLicenseBase): Promise;
/**
* This method allows you to query the version information related to the Kantar Embedder
*/
queryKantarVersion(): Promise;
}
/**
* @public
* Methods that allow you to manipulate your media streams
*/
export interface NorskTransform {
/**
* Encode a video stream to one or more renditions
* using either software or appropriate hardware if available
* @param settings - Encode ladder settings
*/
videoEncode(settings: VideoEncodeSettings): Promise;
/**
* Decode a video stream to a specific type of 'raw' format
* this isn't usually needed because decode will happen automatically for nodes that need raw data
* however if we definitely want a hardware decode and we're creating nodes that accept inMemory raw, we can use this node
* to ensure that the hardware decode takes place
* @param settings - Decode settings
*/
videoDecode(settings: VideoDecodeSettings): Promise;
/**
* Transform a single video stream (rescale, frame rate, etc)
* @param settings - Transform settings
*/
videoTransform(settings: VideoTransformSettings): Promise;
/**
* Interferes with a stream by dropping frames
* Why would you want this? Stick one of these after a decoder and before
* anything else in order to simulate what the world is going to look like if you
* have network problems (packet drops for example) in your ingest
*
* *Just don't forget to remove it again when you've finished testing!*
* @param settings - Chaos monkey settings
*/
streamChaosMonkey(settings: StreamChaosMonkeySettings): Promise;
/**
* Compose multiple video streams together into a single output
* @param settings - Composition settings
*/
videoCompose(settings: VideoComposeSettings): Promise>;
/**
* Create a Media Node performing transcription into subtitles using the
* Amazon Transcribe AWS service.
* @param settings - Settings and credentials for AWS transcribe
*/
audioTranscribeAws(settings: AudioTranscribeAwsSettings): Promise;
/**
* Create a Media Node performing transcription into subtitles using the
* Azure Speech service.
* @param settings - Settings and credentials for Azure transcribe
*/
audioTranscribeAzure(settings: AudioTranscribeAzureSettings): Promise;
/**
* Create a Media Node performing transcription into subtitles using the
* Whisper speech recognition model via the whisper-cpp SDK.
*
* For reference on general concepts https://github.com/ggerganov/whisper.cpp - many settings are directly settings on the
* underlying library and can be evaluted via the CLI tool there also.
* @param settings - Settings and credentials for Whisper transcribe
*/
audioTranscribeWhisper(settings: AudioTranscribeWhisperSettings): Promise;
/**
* Mix multiple audio streams together into a single output,
* with optional gain control on each input.
* @param settings - Settings for the mixer, including the gain vectors
*/
audioMix(settings: AudioMixSettings): Promise>;
/**
* Given an audio stream of N channels, mix it down to M channels through a matrix of NxM gains.
* @param settings - Settings for the mixer, including the gain matrix
*/
audioMixMatrix(settings: AudioMixMatrixSettings): Promise;
/**
* Apply gain to an audio stream
* @param settings - Settings for the gain node
*/
audioGain(settings: AudioGainSettings): Promise;
/**
* Aggregate many single-channel audio streams into a stream with the
* specified channel layout. The streams must all have the same sample format
* and sample rate. The order of the streams provided for the channels is
* important.
* @param settings - Settings for the builder, including the channel layout
* and stream keys specifying the sources for each channel.
*/
audioBuildMultichannel(settings: AudioBuildMultichannelSettings): Promise;
/**
* Split a multichannel audio stream into its individual channels. The first
* channel receives the specified stream key, and each subsequent channel
* increments the stream id on the stream key.
* @param settings - Settings for the splitter
*/
audioSplitMultichannel(settings: AudioSplitMultichannelSettings): Promise;
/**
* Encode an audio stream.
* @param settings - Settings for the encoder, including channel layout and
* bitrate.
*/
audioEncode(settings: AudioEncodeSettings): Promise;
/**
* Methods to allow you to embed watermarks into audio streams
*/
audioWatermark: NorskKantarEmbedder;
/**
* Translate subtitles using the AWS Translate service.
*
* Credentials are provided either via the standard AWS environment variables (for the Norsk server instance),
* EC2 role credentials (IMDSv2), etc via the AWS SDK standard credential provider chain.
*/
subtitleTranslateAws(settings: SubtitleTranslateAwsSettings): Promise;
/**
* Convert subtitles/captions/transcriptions from one format to another
*
* Similar to audio and video encodes, this may happen implicitly as required, but this explicit node allows
* choice of format and conversion parameters to be specified
* @param settings - Conversion settings
*/
subtitleConvert(settings: SubtitleConvertSettings): Promise;
/**
* A node to nudge the timestamps on a stream, which affects how it syncs
* with other streams. Useful for correcting for drift between different
* sources.
*
* Subsequent nudges, via the `nudge` method, are applied gradually.
*
* This functionality is also provided by a `nudge` method on many sources.
* @param settings - Initial nudge plus general node settings.
*/
streamTimestampNudge(settings: StreamTimestampNudgeSettings): Promise;
/**
* Provide a new stream key for a single stream. Cannot be subscribed to
* multiple streams at once.
*
* The stream key is used for identifying streams within multiplexed sources
* and also is translated into URIs for HLS playlists and other resources.
*
* This can be useful if changing sources and wanting to maintain a consistent
* streamkey going into an output
* @param settings - New stream key plus general node settings.
*/
streamKeyOverride(settings: StreamKeyOverrideSettings): Promise;
/**
* Override bitrate and language metadata on streams.
*
* Audio and video bitrate metadata is required for playlists for the
* {@link NorskOutput.cmafMultiVariant} node.
* It is automatically configured for some sources (like RTMP) and in
* cases where re-encoding is done, but is unset for other sources (like SRT).
* @param settings - Bitrate and language metadata plus general node settings.
*/
streamMetadataOverride(settings: StreamMetadataOverrideSettings): Promise;
/**
* Buffer a stream for the specified number of milliseconds. This can be used
* to reduce or eliminate jitter.
* @param settings - Buffer delay time.
*/
jitterBuffer(settings: JitterBufferSettings): Promise;
/**
* Sync multiple streams together by timestamps, queuing frames from streams
* that are behind the others. This is already included in most nodes,
* especially outputs.
*/
streamSync(settings: StreamSyncSettings): Promise;
/**
* This processor does multiple things
* - joins together multiple streams from multiple sources
* - rebases their timestamps so that they all start at the same point
* - sets the program id to a common value
*
* It is useful for syncing multiple incoming streams that on paper are already synchronised but because
* of the time taken to set up connections and subscriptions across various protocols, are off by a few
* hundred milliseconds
*/
streamAlign(settings: StreamAlignSettings): Promise;
/**
* Condition a stream for switching (i.e. for ad insertion)
*
* Provides a mechanism for requesting that a straem be conditioned for switching, with in and out points.
* This means insertion of IDR frames, relevant to both continuous outputs (e.g. TS based), and hinting
* of segmentation breaks for segmented outputs (ie HLS).
*
* This may be used in combination with an {@link NorskTransform.ancillary} node for reacting to SCTE-35 message
* @param settings - Options for the conditioner
*/
streamCondition(settings: StreamConditionSettings): Promise;
/**
* Observe, modify or inject ancillary data such as SCTE-35 or timed metadata.
*
* If intending to send ancillary messages without a specified timestamp this node should be subscribed
* to an audio or video stream from the given program to act as a timing source.
*/
ancillary(settings: AncillarySettings): Promise;
/**
* Combine compatible streams of metadata (this refers to ancillary streams of metadata messages, such as that
* carried in an MPEG-TS PES metadata stream (e.g. KLV), unrelated to operations on the metadata of audio/video/etc streams.
*/
metadataCombine(settings: MetadataCombineSettings): Promise;
}
/**
* @public
* Methods that allow you to control and monitor media streams
*/
export interface NorskControl {
/**
* Switch between multiple input sources via a hard cut. May be used to switch between
* sources of possibly different configurations or without decoding.
* @param settings - Options for the switcher
*/
streamSwitchHard(settings: StreamSwitchHardSettings): Promise>;
/**
* Switch between multiple input sources without interruption, via a transition.
* @param settings - Options for the switcher
*/
streamSwitchSmooth(settings: StreamSwitchSmoothSettings): Promise>;
/**
* Record statistical information about media streams, including bitrate,
* frame rate, and number of keyframes, measured over some configurable
* sampling windows.
*
* Corresponding settings are found on many input and output nodes.
* @param settings - Callback and sampling intervals
*/
streamStatistics(settings: StreamStatisticsSettings): Promise;
/**
* Monitor the volume of an audio stream
* @param settings - Callback and options for the level data
*/
audioMeasureLevels(settings: AudioMeasureLevelsSettings): Promise;
geminiProcessor(settings: GeminiSettings): Promise;
}
/** @public */
export declare class NorskProcessor {
/**
* Implements the {@link NorskControl} interface
*/
control: NorskControl;
/**
* Implements the {@link NorskTransform} interface
*/
transform: NorskTransform;
constructor(client: MediaClient);
}
export {};
//# sourceMappingURL=processor.d.ts.map