import * as grpc from "@grpc/grpc-js"; import { FileTsInputMessage, M3u8MediaInputMessage, M3u8MultiVariantInputMessage, RtmpError_InvalidStreamResponse, RtmpError_UnsupportedAudio, RtmpError_UnsupportedVideo, TcpTsInputMessage, TimestampProgramNudge, TsInputEvent, UdpTsInputMessage, TamsFlowInputMessage, CmafIngestInputMessage, CmafIngestInputEvent, TsTable, SrtTsTable, StreamKey as StreamKeyPB } from "@norskvideo/norsk-api/lib/media_pb"; import { MoqConnectionResult, IrohDedicatedListenerSettings } from "./output"; import { DeckLinkDisplayModeId, DeckLinkPixelFormat, DeckLinkProfileId, DeckLinkVideoConnection, FrameRate } from "../types"; import { MediaClient, MediaNodeState, SourceMediaNode, SourceNodeSettings, StreamStatisticsMixin } from "./common"; import { AacChannelLayout, BrowserEvent, C2paValidationOutcome, C2paVerificationSettings, ChannelLayout, HttpAuth, IceServerSettings, ImageFormat, InputThresholdSettings, Interval, PixelFormat, RtmpServerInputStatus, RtpLinearPcmBitDepth, SampleFormat, SampleRate, SourceTime, SrtInputStatus, SrtMode, TimeDomain, StreamMetadata, SubtitleFragment, TeletextLine, Cta708CharsetSetting, Wave, WebRtcStatsMessage } from "./types"; import { DropRandom } from "./processor"; /** * @public * Base settings for most input nodes * */ export interface InputSettings extends SourceNodeSettings { /** The source name to set on the stream key on the outgoing stream from this node */ sourceName: string; } /** * @public * Base settings for any input node requiring access to a host:port pair * */ export interface RemoteInputSettings extends InputSettings { /** The IP or hostname of the remote server*/ host: string; /** The port the remote server is listening on*/ port: number; } /** * @public * A description of a LinearPCM stream being delivered via RTP * */ export interface RtpLinearPcm { kind: "linearpcm"; /** The sample rate of the stream */ sampleRate: SampleRate; /** The channel layotu the stream */ channelLayout: ChannelLayout; /** The bit depth of the stream */ bitDepth: RtpLinearPcmBitDepth; } /** * @public * A description of an Eac3 stream being delivered via RTP * */ export interface RtpEac3 { kind: "eac3"; /** The clock rate of the stream */ clockRate: number; /** The language code (this will end up in outgoing metadata). RFC 5646 language tag. */ languageCode?: string; ec3Extension: boolean; complexityIndex: number; } /** * @public * A description of a Mpeg4 Generic Aac stream * */ export interface RtpMpeg4GenericAacHbr { kind: "mpeg4-generic-aac-hbr"; config: string; } /** * @public * A description of an H264 stream delivered over RTP * */ export interface RtpH264 { kind: "h264"; /** The clock rate of the stream */ clockRate: number; } /** * @public * A description of an HEVC stream delivered over RTP * */ export interface RtpHEVC { kind: "hevc"; /** The clock rate of the stream */ clockRate: number; } /** * @public * A description of an incoming RTP stream * */ export interface RtpStreamSettings { /** A streamID to assign to the outgoing stream key */ streamId: number; /** The IP Address to join the RTP stream on */ ip: string; /** The interface to bind to, "loopback" and "any" are special cases * and anything else will be interpreted as the name of a network interface */ interface: string; /** The port to connect to for the RTP stream itself */ rtpPort: number; /** The port to connect to for the associated RTCP stream */ rtcpPort: number; /** A description of the stream being joined */ streamType: RtpLinearPcm | RtpEac3 | RtpMpeg4GenericAacHbr | RtpH264 | RtpHEVC; } /** * @public * Settings for an RTP input * see: {@link NorskInput.rtp} * */ export interface RtpInputSettings extends SourceNodeSettings, StreamStatisticsMixin { sourceName: string; streams: readonly RtpStreamSettings[]; } /** * @public * The stream keys in an RTMP input stream */ export type RtmpServerStreamKeys = { audioStreamKey: StreamKeyPB; videoStreamKey: StreamKeyPB; }[]; /** * @public * see: {@link NorskInput.rtp} */ export declare class RtpInputNode extends SourceMediaNode { /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(nudge: number): void; } /** * @public * Settings to control how RTMP streams can be included as sources in your media workflow * see: {@link NorskInput.rtmpServer} */ export interface RtmpServerInputSettings extends SourceNodeSettings, StreamStatisticsMixin { /** The port the RTMP server should listen on */ port?: number; ssl?: boolean; sslOptions?: { certFile?: string; keyFile?: string; }; /** * On connect callback, use to accept/reject connections given app/url in use * @eventProperty */ onConnection?: ( /** The connection ID, unique to this RtmpServer node */ connectionId: string, /** The RTMP "app" field from the connection string */ app: string, /** The full URL of the RTMP connection string */ url: string) => { accept: true; } | { accept: false; reason?: string; }; /** * On stream callback, set up the stream keys for a given stream or reject the stream * @eventProperty */ onStream?: ( /** The connection ID, unique to this RtmpServer node */ connectionId: string, /** The RTMP "app" field from the connection string */ app: string, /** The full URL of the RTMP connection string */ url: string, /** The Norsk streamId of this media stream */ streamId: number, /** TODO - publishingName */ publishingName: string) => OnStreamResult; /** * Called when the connection status has changed (e.g. when the RTMP connection drops) * @eventProperty */ onConnectionStatusChange?: ( /** The connection ID, unique to this RtmpServer node */ connectionId: string, /** The new connection state */ status: RtmpServerInputStatus, /** The audio and video stream keys that were present in the stream at the time of the status change */ streamKeys: { audioStreamKey: StreamKeyPB; videoStreamKey: StreamKeyPB; }[]) => void; onConnectionError?: ( /** The connection ID, unique to this RtmpServer node */ connectionId: string, /** The error */ error: RtmpError_UnsupportedVideo | RtmpError_UnsupportedAudio | RtmpError_InvalidStreamResponse) => void; onConnectionBytesRead?: ( /** The connection ID, unique to this RtmpServer node */ connectionId: string, /** The number of bytes read, as reported by the peer */ bytesRead: bigint) => void; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * Return type to enable control of an RTMP stream once media arrives on it */ export type OnStreamResult = /** Accept the stream */ { accept: true; videoStreamKey: StreamKeyPB | StreamKeySettings; audioStreamKey: StreamKeyPB | StreamKeySettings; } /** Reject the stream */ | { accept: false; reason: string; }; /** @public */ export interface StreamKeySettings { /** Source name. Default: the rtmp app */ sourceName?: string; /** Program number. Default: 1 */ programNumber?: number; /** Stream Id. Default: 1 for audio, 2 for video */ streamId?: number; /** Rendition name. Default: the stream publishing name */ renditionName?: string; } /** * @public * see: {@link NorskInput.rtmpServer} */ export declare class RtmpServerInputNode extends SourceMediaNode { /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(sourceName: string, programNumber: number, nudge: number): void; /** * @public * Close the given connection (i.e. a single client rather than the listeningserver) */ closeConnection(connectionId: string): void; } declare enum TsInputType { TsFile = 0, Srt = 1, Udp = 2, M3u8 = 3, Tams = 4, Tcp = 5, M3u8MultiVariant = 6 } declare class TsCommonInputNode extends SourceMediaNode { constructor(tsType: TsInputType, client: MediaClient, unregisterNode: (node: MediaNodeState) => void, settings: SourceNodeSettings & StreamStatisticsMixin & TsCommonInputSettings, nudgeFn: (nudge: TimestampProgramNudge) => SourceMessage, onEof: (() => void) | undefined, grpcStartFn: () => grpc.ClientDuplexStream); /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(programNumber: number, nudge: number): void; } /** * @public * Settings to control SDI capture through a DeckLink card * see: {@link NorskInput.deckLink} */ /** * @public * Which subtitle format (if any) the SDI input is expected to carry. * * A real SDI signal will usually carry at most one subtitle format; mixing * OP47 teletext with SMPTE 334 CDP (CEA-708/608) is technically possible * but rare and unsupported by Norsk. Configuring this explicitly means the * input only advertises the subtitle context for the chosen format, so * downstream consumers see a single, unambiguous subtitle stream. */ export type DeckLinkSubtitleKind = "none" | "teletext" | "cta708" | "cta608"; /** * @public * Which ancillary data format (if any) the SDI input should decode. Orthogonal * to subtitles — SCTE-104 can in principle coexist with OP47/CEA on the same * signal, although this combination is rare in practice. * * "none" — do not decode any ancillary data * * "scte104" — SCTE-104 splice commands (SMPTE 2010, DID=0x41 SDID=0x07). * Decoded messages are exposed as SCTE-35 `SpliceInfoSection` * on the DeckLink input's ancillary output, using the current * video frame's PTS to resolve `pre_roll_time` offsets. */ export type DeckLinkAncillaryKind = "none" | "scte104"; export interface DeckLinkInputSettings extends InputSettings, StreamStatisticsMixin { /** Which card to use */ cardIndex: number; /** The audio channel layout for the input */ channelLayout: ChannelLayout; /** SDI or HDMI capture */ videoConnection: DeckLinkVideoConnection; /** Typically left undefined, but can be used to force capture for a specific {@link DeckLinkDisplayModeId}. If * the source is not currently in this mode, then no capture will occur. */ displayModeId?: DeckLinkDisplayModeId; pixelFormat?: DeckLinkPixelFormat; /** Hardware profile to activate on the card before starting capture. * Only relevant for cards that support multiple profiles (e.g. DeckLink Duo 2, Quad 2). * If the card is already in the requested profile, this is a no-op. * If omitted, the card's current profile is used as-is. */ profileId?: DeckLinkProfileId; cpuList?: number[]; /** * Which subtitle format (if any) to extract from SDI VANC. Default: "none". * * "teletext" — OP47 teletext (DID=0x43 SDID=0x02) * * "cta708" — CEA-708 in SMPTE 334 CDP (DID=0x61 SDID=0x01) * * "cta608" — CEA-608 in SMPTE 334 CDP (DID=0x61 SDID=0x01) */ subtitles?: DeckLinkSubtitleKind; /** * Which ancillary format (if any) to extract from SDI VANC. Default: "none". * * "scte104" — SCTE-104 splice commands (DID=0x41 SDID=0x07), surfaced * as SCTE-35 sections on the ancillary output pin. */ ancillary?: DeckLinkAncillaryKind; /** Enable RP 188 VITC timecode extraction from SDI VANC. Default: false. * When enabled, timecodes are set as `sourceTime` on captured frames. */ captureTimecode?: boolean; /** Enable OP47 teletext extraction from SDI VANC. Default: false. */ captureTeletext?: boolean; /** Enable CEA-608/708 extraction from SDI VANC (SMPTE 334 CDP). Default: false. */ captureCea?: boolean; /** Enable SCTE-104 splice command extraction from SDI VANC. Default: false. */ captureScte104?: boolean; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * SDI capture through a DeckLink card. * see: {@link NorskInput.deckLink}. */ export declare class DeckLinkInputNode extends SourceMediaNode { /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(nudge: number): void; } export type SourceTimeStateLost = { state: "signalLost"; }; export type SourceTimeStateAcquired = { state: "signalAcquired"; sourceTime: SourceTime; }; export type SourceTimeState = SourceTimeStateLost | SourceTimeStateAcquired; /** * @public * Settings to control SDI capture through a Deltacast card * see: {@link NorskInput.deltaCast} */ export interface DeltacastInputSettings extends SourceNodeSettings, StreamStatisticsMixin { /** Which device to use */ deviceId: number; channels: { /** Which channel on the device to use */ channelIndex: number; /** sourceName of this channel **/ sourceName: string; }[]; /** Should video be captured? Defaults to true, but for applications that only require the audio * there is a small efficiency gain by setting to false */ captureVideo?: boolean; /** * An SDI signal can contain up to 16 (3G) or 32 (6G / 12G) audio channels, which are * transmitted as groups of 4. For example, a single stereo signal would typically be * encoded with the left audio on the first channel of the first group, and the right * audio as the second channel of the first group. The remaining 2 channels on the first * group will contain silence. Deltacast input captures all audio channels that are present * in the signal and returns them as mono streams; the audioBuidMultichannel node can be * used to combine these mono streams into stereo, 5.1 etc. * The audioChannelMask is a bit field that indicates which streams should be returned out * of those present in the signal. Taking the stereo signal example from above, a sensible * mask would be 0x3, indicating that channels 0 and 1 should be returned - thus saving * your code from needing to deal with channels 2 and 3, which you know to just be silent. * If you set a bit that is *not* present in the signal, then no stream will be created - * only streams present in the signal will be returned. * If left undefined, then a default of 0xFFFFFFFF is used - i.e., capture all */ audioChannelMask?: number; /** * Called when either a VITC timecode is detected, or having previously detected a timestamp it stops being present */ onSourceTimeStateChange?: (sourceTimeState: SourceTimeState) => void; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * SDI capture through a Deltacast card. * see: {@link NorskInput.deltaCast}. */ export declare class DeltacastInputNode extends SourceMediaNode { /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(nudge: number): void; } /** * @public * Settings to control NDI capture * see: {@link NorskInput.ndi} */ /** * @public * Settings to configure an MXL (Media eXchange Layer) input. * Reads v210 video and float32 audio from an MXL domain. * see: {@link NorskInput.mxl} */ export interface MxlInputSettings extends SourceNodeSettings, StreamStatisticsMixin { /** Source name for this input */ sourceName: string; /** MXL domain path (e.g. "/dev/shm/mxl") */ domain: string; /** Explicit flow UUIDs to read. If set, other selectors are ignored. */ flowIds?: string[]; /** Match flows whose NMOS format URN matches any of these (e.g. ["urn:x-nmos:format:video", "urn:x-nmos:format:audio"]) */ matchFormats?: string[]; /** Match flows whose grouphint tag contains this string */ matchGroupHint?: string; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * MXL Input Node - reads media from an MXL shared memory domain. * see: {@link NorskInput.mxl} */ export declare class MxlInputNode extends SourceMediaNode { /** Nudge the timestamp corrector */ nudge(nudge: number): void; } export interface NdiInputSettings extends SourceNodeSettings, StreamStatisticsMixin { /** sourceName of this capture */ sourceName: string; /** the NDI source name or url to capture from, which can be found through `ndiDiscovery` */ ndiSource: { url: string; } | { name: string; }; /** The receive name to publish to the source */ ndiReceiveName: string; /** Override the source frame rate - should only be used if you have reason to beleive that the frame rate announced by the source is incorrect. * Selecting a frame rate that differs from the source will lead to undefined behaviour */ sourceFrameRate?: { variable: undefined; } | { fixed: FrameRate; }; /** Called when the receiver is initialised; you could use this to avoid starting other nodes until frame reception is guaranteed */ onInitialised?: () => void; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * NDI Capture * see: {@link NorskInput.ndi}. */ export declare class NdiInputNode extends SourceMediaNode { /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(nudge: number): void; } /** @public */ export type WhipInputStatus = "disconnected"; /** @public */ export interface WhipInputSettings extends SourceNodeSettings, 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[]; name: string; onConnection?: (client: { sessionId: string; }) => WhipConnectionResult; /** * Called when the connection status has changed for an individual client (eg the client is disconnected by timeout or request) * @eventProperty */ onConnectionStatusChange?: (change: { /** The new connection state */ status: WhipInputStatus; /** The sessionId of the client connection that changed status */ sessionId: string; }) => void; /** * Callback giving stats from the WebRTC stack for an individual ingest session */ onStats?: (stats: WebRtcStatsMessage) => void; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * The return value for the {@link WhipInputSettings.onConnection} callback * determining what to do with an incoming stream */ export type WhipConnectionResult = { accept: true; sourceName: string; programNumber?: number; } | { accept: false; }; /** * @public * see: {@link NorskInput.whip} */ export declare class WhipInputNode extends SourceMediaNode { /** @public The URL of the local test client */ clientUrl: string; /** @public The URL of the WHIP endpoint */ endpointUrl: string; /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(sourceName: string, programNumber: number, nudge: number): void; /** * @public * Closes the given client session * */ closeSession(sessionId: string): void; } /** * @public * The standard settings for any node reading from a file * */ export interface LocalFileInputSettings extends InputSettings { /** The file to be read from */ fileName: string; /** An optional callback that will be invoked when file end is reached */ onEof?: () => void; } /** * @public * see: {@link NorskInput.fileWebVtt} */ export interface WebVttFileInputSettings extends InputSettings { /** The file to be read from */ fileName: string; /** Language tag to associate with the stream (optional) */ language?: string; /** Rendition Name to associate with the stream (optional, default "default") */ renditionName?: string; } /** * @public * see: {@link NorskInput.fileWebVtt} */ export declare class FileWebVttInputNode extends SourceMediaNode { } /** @public */ export interface M3u8WebVttInputSettings extends InputSettings { /** URL of a WebVTT *media* playlist (typically referenced by an EXT-X-MEDIA TYPE=SUBTITLES entry of a master). */ url: string; /** Optional BCP-47 language tag (e.g. "en", "fr"). */ language?: string; /** Optional rendition name (default "default"). */ renditionName?: string; /** * Playback mode. `"fromStart"` (default) replays the playlist from its * oldest visible segment; `"live"` follows the live edge. Note that * `"fromStart"` against a VOD playlist will burst cues at upstream-fetch * rate rather than wall-clock — see the engine's M3u8WebVttInput notes. */ playMode?: "fromStart" | "live"; } /** * @public * see: {@link NorskInput.m3u8WebVtt} */ export declare class M3u8WebVttInputNode extends SourceMediaNode { } export type StreamSubtitlesInputFormat = "webvtt" | "ttml" | "fragments" | { type: "teletext"; page: number; magazine: number; }; /** * @public * see: {@link NorskInput.streamSubtitles} */ export interface StreamSubtitlesInputSettings extends InputSettings { /** Language tag to associate with the stream (optional) */ language?: string; /** Rendition Name to associate with the stream (optional, default "default") */ renditionName?: string; /** Format to generate. Restricts the subtitles that can be later injected */ format: StreamSubtitlesInputFormat; } /** * @public * see: {@link NorskInput.StreamSubtitles} */ export declare class StreamSubtitlesInputNode extends SourceMediaNode { /** * @public * Send a WebVTT subtitle cue (or multiple cues) given as a WebVTT document, i.e. containing "WEBVTT" and time ranges/cue text. Timestamps are * relative to real time, according to the first timestamp sent. It is recommended to send an empty message on initialisation to anchor these timestamps. */ sendChunk(chunk: string): void; /** * @public * Send a WebVTT-style subtitle cue given the body text and the time range of the cue. The timestamp is a Norsk internal timestamp, which may * be observed (and perhaps offset calculated) from some other node, such as a stream timestamp report node. */ sendCue(cue: { startTimestamp: Interval; endTimestamp: Interval; text: string; }): void; /** * @public * Send timed text fragments (ideally timed words) which can later be split and formatted into subtitle cues * * Timestamps are required for each fragment, which should of course be ordered, and the start/end of the run of fragments. * The presence of the overall start/end time allows signalling of a gap with no speech so as not to hold up accumulated cues/other * streams downstream. It is advisable to send an empty message initially when the appropriate timestamp is known. */ sendFragments(message: { fragments: SubtitleFragment[]; startTimestamp: Interval; endTimestamp: Interval; }): void; /** * @public * Send a TTML subtitling document. * * This may be an individual cue or ISD, or a segment comprising multiple cues. A timestamp and corresponding value for the media timeline is required, as in DVB TTML, * for an individual cue the timestamp of the document can simply be the cue timestamp (cue is untimed or starts at 00:00:00), or an offset can be calculated to use an existing * document (fragment) without modification. * * The timestamp is a Norsk internal timestamp, which may be observed (and perhaps offset calculated) from some other node, such as a stream timestamp report node. */ sendTtml(cue: { startTimestamp: Interval; endTimestamp: Interval; mediatime_ms: number; document: string; }): void; /** * @public * Send a Teletext subtitle page * */ sendTeletext(teletext: { startTimestamp: Interval; page: TeletextLine[]; }): void; /** * @public * Applies a nudge to the outgoing stream timestamps by the specified number of milliseconds. * Unlike audio/video inputs this nudge is not gradual but abrupt, as the input is not continuous * */ nudge(nudge: number): void; } /** @public */ export interface FileTsInputSettings extends LocalFileInputSettings, StreamStatisticsMixin, TsCommonInputSettings { /** Whether to loop back to the start of the file after reaching the end */ loop?: boolean; /** Whether to start paused or already playing (default: playing) */ start?: 'playing' | 'paused'; /** * Drop raw input packets ala {@link NorskTransform.streamChaosMonkey}. Leaving this undefined means don't drop any packets * For testing, you *really* don't want this in a live system. **/ chaosDropPackets?: DropRandom; /** * Playback rate multiplier. Defaults to realtime (1). Values greater than 1 * play the file faster than realtime - useful for speeding up file-based * tests and VOD-style fast transcode. Only meaningful for file inputs. */ playbackRate?: number; } /** @public */ export interface TsPid { pid: number; streamType: string; } /** @public */ export interface TsProgram { programNumber: number; streams: TsPid[]; } /** @public */ export interface TsContext { programs: TsProgram[]; } export interface SrtTsContext extends TsContext { source: string; } /** @public */ export interface TsCommonInputSettings { /** Callback to be invoked on receiving the raw TS context. This may contain additional streams which are unsupported * by Norsk and would not appear in the node output, pids which have no data and thus will not appear in the node output (yet). */ onTsContext?: (context: TsContext) => void; /** * Callback to be invoked on receiving a TS PSI/SI table/section */ onTsTable?: (table: TsTable) => void; /** * Called when either a VITC timecode is detected, or having previously detected a timestamp it stops being present */ onSourceTimeStateChange?: (sourceTimeState: SourceTimeState) => void; /** * Optionally filter a single program from MPTS at decode time */ programFilter?: number; /** * Character set used to interpret CTA-708 **P16** (16-bit) captions — for * East-Asian services whose P16 code set is a legacy DBCS rather than Unicode. * The code set is signalled out of band, so it must be chosen per input; it * does not affect Latin/ASCII text. Defaults to `'unicode'`. */ cta708Charset?: Cta708CharsetSetting; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** @public */ export interface FileTsInputSettingsUpdate { /** Whether to loop back to the start of the file after reaching the end */ loop?: boolean; } /** * @public * see: {@link NorskInput.fileTs} */ export declare class FileTsInputNode extends TsCommonInputNode { updateSettings(settings: FileTsInputSettingsUpdate): void; pause(): void; play(): void; } /** * @public * The return value for the {@link SrtInputSettings.onConnection} callback * determining what to do with an incoming stream */ export type SrtConnectionResult = /** Accept the stream */ { accept: true; /** The source name to assign to the connection */ sourceName: string; } /** Reject the stream */ | { accept: false; }; /** * @public * Settings for an SRT Input node * see: {@link NorskInput.srt} */ export interface SrtCommonInputSettings { /** The IP or hostname of the remote server*/ host: string; /** * The port to listen on in listener mode, or to connect to in caller mode * * In listener mode the port may be given as 0 to bind to an automatically assigned port, which can be retrieved in `onBind`. */ port: number; /** * The mode to act in (caller or listener) */ mode: SrtMode; /** * Passphrase for encryption */ passphrase?: string; /** * Stream ID to set on the socket when acting in caller mode */ streamId?: string; /** * The latency value in the receiving direction of the socket (SRTO_RCVLATENCY) */ receiveLatency?: number; /** * The latency value provided by the sender side as a minimum value for the receiver (SRTO_PEERLATENCY) */ peerLatency?: number; /** * Input bandwidth (SRTO_INPUTBW) */ inputBandwidth?: number; /** * Overhead bandwidth (SRTO_OHEADBW) */ overheadBandwidth?: number; /** * Max bandwidth (SRTO_MAXBW) */ maxBandwidth?: number; /** * Idle timeout after which to disconnect if no data received. If unspecified a default timeout is used */ peerIdleTimeoutMs?: number; /** * Interval in milliseconds at which to poll the underlying SRT socket for connection status changes (driving {@link onConnectionStatusChange}). When unspecified a default is used. */ statusPollIntervalMs?: number; /** * Interval in milliseconds at which to sample SRT socket statistics. Stats feed metrics, so tune this to the rate at which you want metric updates. When unspecified a default is used. */ statsPollIntervalMs?: number; /** * Whether to enable the too-late-packet-drop mechanism (SRTO_TLPKTDROP) - default true. On a receiver you may want to disable * this to avoid dropping packets whose wallclock-timing may be slightly too late to deliver to norsk, but actually the MPEG-TS timing * plus any workflow buffering/latency is enough to absorb a slight delay. */ tlpktdrop?: boolean; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; /** * Called when a listener-mode SRT input binds to the interface */ onBind?: (info: { port: number; }) => void; /** * On connect callback, notifying that a new caller has connected (in listener mode) and set the source name accordingly * @eventProperty */ onConnection?: ( /** The stream_id sent on the SRT socket (or empty if none was set) */ streamId: string, /** * Identifier indicating which connection this message refers to (for a * listener which may have multiple connections) */ index: number, /** The address of the remote host */ remoteHost: string) => SrtConnectionResult; /** * Called when the connection status has changed (e.g. when the SRT socket is closed) * @eventProperty */ onConnectionStatusChange?: ( /** The new connection state */ status: SrtInputStatus, /** The source name assigned to the connection which changed status */ sourceName: string | undefined, /** * Identifier indicating which connection this message refers to (for a * listener which may have multiple connections) */ index: number) => void; /** When specified dump the raw source input for debug purposes to the given directory */ debugDumpSource?: string; /** when specified, drop data until the input is ticking at realtime */ startupThreshold?: InputThresholdSettings; /** * Optionally filter a single program from MPTS at decode time */ programFilter?: number; /** * Character set used to interpret CTA-708 **P16** (16-bit) captions — for * East-Asian services whose P16 code set is a legacy DBCS rather than Unicode. * The code set is signalled out of band, so it must be chosen per input; it * does not affect Latin/ASCII text. Defaults to `'unicode'`. */ cta708Charset?: Cta708CharsetSetting; } /** * @public * Settings for an SRT Input node * see: {@link NorskInput.srt} */ export interface SrtInputSettings extends SrtCommonInputSettings, InputSettings, StreamStatisticsMixin { onTsContext?: (context: SrtTsContext) => void; /** * Callback to be invoked on receiving a TS PSI/SI table/section */ onTsTable?: (table: SrtTsTable) => void; /** * Called when either a VITC timecode is detected, or having previously detected a timestamp it stops being present */ onSourceTimeStateChange?: (sourceTimeState: SourceTimeState) => void; /** * Drop raw input packets ala {@link NorskTransform.streamChaosMonkey}. Leaving this undefined means don't drop any packets * For testing, you *really* don't want this in a live system. **/ chaosDropPackets?: DropRandom; } /** * @public * Settings for an AAC raw bitstream codec (no ADTS/LATM encapsulation) */ export type AacRawCodec = { type: "aac_raw"; sampleRate: SampleRate; channelLayout: AacChannelLayout; }; /** * @public * Settings for an MP3 codec (stream contains metadata in mp3 header) */ export type Mp3Codec = { type: "mp3"; }; /** * @public * Settings for an LPCM codec */ export type PcmCodec = { type: "pcm"; sampleRate: SampleRate; channelLayout: ChannelLayout; endianness: "big" | "little"; bitDepth: 16 | 20 | 24; }; export type SrtRawCodec = AacRawCodec | Mp3Codec | PcmCodec; /** * @public * Settings for an SRT Raw Input node * see: {@link NorskInput.srtRaw} */ export interface SrtRawInputSettings extends SrtCommonInputSettings, InputSettings, StreamStatisticsMixin { codec: SrtRawCodec; } /** * @public * see: {@link NorskInput.srt} */ export declare class SrtInputNode extends SourceMediaNode { /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(sourceName: string, programNumber: number, nudge: number): void; /** * @public * Closes a connected stream as specified by 'streamIndex' * @param streamIndex - the index of the stream to be terminated * */ closeStream(streamIndex: number): void; } /** * @public * see: {@link NorskInput.srtRaw} */ export declare class SrtRawInputNode extends SourceMediaNode { /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(sourceName: string, programNumber: number, nudge: number): void; /** * @public * Closes a connected stream as specified by 'streamIndex' * @param streamIndex - the index of the stream to be terminated * */ closeStream(streamIndex: number): void; } /** * @public * Settings for a UDP Transport Stream input * see: {@link NorskInput.udpTs} * */ export interface UdpTsInputSettings extends RemoteInputSettings, TsCommonInputSettings { /** Optional interface to bind to */ interface?: string; /** Timeout in milliseconds before determining the input is closed */ timeout?: number; /** Whether to expect the input TS to be encapsulated in RTP via RFC 2250 (default: false) */ rtpDecapsulate?: boolean; /** When specified dump the raw source input for debug purposes to the given directory */ debugDumpSource?: string; /** when specified, drop data until the input is ticking at realtime */ startupThreshold?: InputThresholdSettings; /** * Drop raw input packets ala {@link NorskTransform.streamChaosMonkey}. Leaving this undefined means don't drop any packets * For testing, you *really* don't want this in a live system. **/ chaosDropPackets?: DropRandom; } /** * @public * see: {@link NorskInput.udpTs} */ export declare class UdpTsInputNode extends TsCommonInputNode { } /** * @public * Settings for a TCP Transport Stream input. Norsk acts as the TCP client, * connecting out to the configured host/port and reconnecting on failure. * see: {@link NorskInput.tcpTs} * */ export interface TcpTsInputSettings extends RemoteInputSettings, TsCommonInputSettings { /** Idle timeout in milliseconds - a connection that delivers no data for this long is dropped and reconnected (default: 1000) */ timeout?: number; /** Minimum number of bytes to gather before passing data downstream (default: 1316, seven TS packets) */ minReadBytes?: number; /** Flush any gathered bytes after this many milliseconds of quiet rather than waiting for minReadBytes (default: 50) */ lingerMs?: number; /** When specified dump the raw source input for debug purposes to the given directory */ debugDumpSource?: string; /** when specified, drop data until the input is ticking at realtime */ startupThreshold?: InputThresholdSettings; /** * Drop raw input data ala {@link NorskTransform.streamChaosMonkey}. Leaving this undefined means don't drop anything * For testing, you *really* don't want this in a live system. **/ chaosDropPackets?: DropRandom; } /** * @public * see: {@link NorskInput.tcpTs} */ export declare class TcpTsInputNode extends TsCommonInputNode { } /** @public */ export interface M3u8MediaInputSettings extends InputSettings { url: string; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * see: {@link NorskInput.m3u8Media} */ export declare class M3u8InputNode extends TsCommonInputNode { } /** @public */ export interface M3u8MultiVariantInputSettings extends InputSettings { /** URL of the HLS *master* (multivariant) playlist. */ url: string; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. * * Renditions enumerated from the master always share a TimeDomain with each * other regardless of this setting; this knob only ties them to other * inputs outside this node. Omit for the default (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * see: {@link NorskInput.m3u8MultiVariant} * * Pulls an HLS master playlist and emits a single set of streams covering * every TS rendition the master enumerates. All renditions share one * TimeDomain, so their timestamps are anchored to a common clock. * * Subtitle (`EXT-X-MEDIA TYPE=SUBTITLES`) renditions are not consumed by this * input today - use `NorskInput.m3u8WebVtt` per subtitle rendition for now. */ export declare class M3u8MultiVariantInputNode extends TsCommonInputNode { } /** @public */ export interface TamsFlowInputSettings extends InputSettings { /** URL of the TAMS service, eg http://example.com:12345/shiny-tams-api/ */ url: string; /** * IDs of all the flows to include in this input. These should be either elementary flows with * overlapping timelines covering the period to play, or a flow collecting such flows */ flowIds: string[]; /** * The flow timestamp to start playout (optionally, if omitted will be from the start) */ startPosition?: string; /** When specified dump the raw source input for debug purposes to the given directory */ debugDumpSource?: string; /** HTTP authentication scheme to use */ auth?: HttpAuth; playMode?: "live" | "once"; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * see: {@link NorskInput.tamsFlow} */ export declare class TamsFlowInputNode extends TsCommonInputNode { } /** * @public * Settings for a Browser Application (Chromium Embedded Framework - CEF). * Multiple browser input nodes will share an underlying CEF instance if * the BrowserAppSettings are the same * */ export interface BrowserAppSettings { /** @deprecated The path to store the browser cache. Should be unique across instances */ cachePath?: string; /** @deprecated The path for the CEF log file. Should be unique across instances */ logFile?: string; /** The logging severity for CEF */ logSeverity: "emergency" | "alert" | "critical" | "error" | "warning" | "notice" | "info" | "debug"; /** GPU Support - note, requires specific host setup */ gpuSupport?: "nvidia-egl" | "nvidia-vulkan"; /** Additional Chromium args (as documented in https://peter.sh/experiments/chromium-command-line-switches/). */ additionalArgs: string[]; cpuList: number[]; } /** * @public * Settings for a Browser Input * see: {@link NorskInput.browser} * */ export interface BrowserInputSettings extends SourceNodeSettings, StreamStatisticsMixin { /** The CEF settings to use for this browser input */ appConfig?: BrowserAppSettings; /** The url to load in the browser session */ url: string; /** This is the resolution of the window opened to render the page * This is therefore also output resolution of the generated video */ resolution: { width: number; height: number; }; /** The source name to populate the outgoing stream key with */ sourceName: string; /** The frame rate at which to generate video from the web page * Note: If the web page is static, this will just mean the initial frame * is duplicated at the required frame rate * */ frameRate: FrameRate; /** An optional callback for reacting to events from the embedded browser * At the very least this is useful for logging events (such as a 404) * */ onBrowserEvent?: (event: BrowserEvent) => void; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * A settings update for a running browser * see: {@link BrowserInputNode.updateConfig} * */ export interface BrowserInputSettingsUpdate { /** Optionally, a new URL to load within the active session */ url?: string; /** Optionally, a new resolution to use for outgoing video */ resolution?: { width: number; height: number; }; } /** * @public * see: {@link NorskInput.browser} */ export declare class BrowserInputNode extends SourceMediaNode { /** * @public * Supply new config for an active web browser session * */ updateConfig(settings: BrowserInputSettingsUpdate): void; /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(nudge: number): void; } /** * @public * Settings for an Audio Signal Generator * see: {@link NorskInput.audioSignal} * */ export interface AudioSignalGeneratorSettings extends SourceNodeSettings { /** The source name to set in the stream key of the outgoing stream */ sourceName: string; /** The stream id for the stream key of the outgoing stream. Defaults to 1 */ streamId?: number; /** The audio channel layout of the generated stream */ channelLayout: ChannelLayout; /** The sample rate of the generated stream */ sampleRate: SampleRate; /** The sample format to use. Default: "fltp" */ sampleFormat?: SampleFormat; /** The language tag to use. Defaults to no language */ language?: string; /** Number of audio samples per frame. Defaults to 1024 */ numSamplesPerFrame?: number; /** Number of frames to output. Defaults to infinite */ numFrames?: number; /** * Waveform - construct a {@link Wave} directoy, or from DMTF digits via {@link mkDtmf} * * If unspecified an arbitrary default signal is generated */ wave?: Wave; /** * Playback rate multiplier. Defaults to realtime (1). Values greater than 1 * generate faster than realtime - useful for speeding up tests and * VOD-style fast generation. */ playbackRate?: number; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * see: {@link NorskInput.audioSignal} */ export interface AudioSignalGeneratorSettingsUpdate { /** * Updated waveform. If unspecified the originally configured waveform is retained */ wave?: Wave; } /** * @public * see: {@link NorskInput.audioSignal} */ export declare class AudioSignalGeneratorNode extends SourceMediaNode { /** @public */ updateConfig(update: AudioSignalGeneratorSettingsUpdate): void; } /** * @public * Settings for an Video Testcard Generator * see: {@link NorskInput.videoTestCard} * */ export interface VideoTestcardGeneratorSettings extends SourceNodeSettings { /** The source name to set in the stream key of the outgoing stream */ sourceName: string; /** The stream id for the stream key of the outgoing stream. Defaults to 1 */ streamId?: number; /** The number of frames to send before shutting down */ numberOfFrames?: number; /** Resolution of the test card stream **/ resolution: { width: number; height: number; }; /** Framerate of the produced video stream **/ frameRate: { frames: number; seconds: number; }; /** The pattern to use on the test card (if any) */ pattern: Pattern; /** Optional pixel format of the raw stream **/ pixelFormat?: PixelFormat; /** Optionally make an interlaced source */ interlaced?: boolean; /** * Playback rate multiplier. Defaults to realtime (1). Values greater than 1 * generate faster than realtime - useful for speeding up tests and * VOD-style fast generation. */ playbackRate?: number; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } export type Pattern = "black" | "smpte75" | "smpte100"; /** * @public * see: {@link NorskInput.audioSignal} */ export declare class VideoTestcardGeneratorNode extends SourceMediaNode { } /** * @public * Settings for an image file source * see: {@link NorskInput.fileImage} * */ export interface FileImageInputSettings extends SourceNodeSettings, StreamStatisticsMixin { /** The source name to set in the stream key of the outgoing stream */ sourceName: string; /** the filename to read the image from */ fileName: string; /** The file format for the image. Will be inferred from the file name if not specified. */ imageFormat?: ImageFormat; /** Optional hardware acceleration to upload frames in */ hardwareAcceleration?: 'quadra'; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * see: {@link NorskInput.fileImage} */ export declare class FileImageInputNode extends SourceMediaNode { } /** * @public * Settings for an File Based Mp4 Input * see: {@link NorskInput.fileMp4} */ export interface FileMp4InputSettings extends SourceNodeSettings, StreamStatisticsMixin { /** The source name to set in the stream key of the outgoing stream */ sourceName: string; /** Path to the MP4 file to read */ fileName: string; /** Callback to be notified when the file ends */ onEof?: () => void; /** Callback to be notified when the file loops on hitting the end */ onLoop?: () => void; /** Callback to be notified when the file reaches the specified stop position */ onStopPosition?: () => void; /** Callback to be notified when playback is approaching the end of the file. Requires eofWarningMs to be set. */ onApproachingEof?: () => void; /** Callback to be notified when the file is initially read */ onInfo?: (info: FileMp4Info) => void; /** Whether to loop back to the start of the file after reaching the end (default false) */ loop?: boolean; /** Whether to start paused or already playing (default: playing) */ start?: 'playing' | 'paused'; /** If set, fire onApproachingEof when playback is within this many ms of the end of the file */ eofWarningMs?: number; /** * Playback rate multiplier. Defaults to realtime (1). Values greater than 1 * play the file faster than realtime - useful for speeding up file-based * tests and VOD-style fast transcode. Only meaningful for file inputs; has no * effect on live/network sources. */ playbackRate?: number; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * Settings for updating a file-based Mp4 Input * see: {@link FileMp4InputNode.updateSettings} */ export interface FileMp4InputSettingsUpdate { /** Whether to loop back to the start of the file after reaching the end */ loop?: boolean; } /** * @public * Information about an Mp4 File * */ export interface FileMp4Info { /** The duration of the Mp4 file in millseconds (if known) */ durationMs?: number; /** The total length of the mp4 file in bytes, if known */ byteLength?: number; trackInfo: FileMp4TrackInfo[]; } /** * @public * Information about an Mp4 File track (i.e. an audio or video stream) * */ export interface FileMp4TrackInfo { metadata?: StreamMetadata; /** The duration of the Mp4 track in millseconds (if known) */ durationMs?: number; } /** * @public * see: {@link NorskInput.fileMp4} */ export declare class FileMp4InputNode extends SourceMediaNode { /** * @public * Applies a gradual nudge to the outgoing stream timestamps by the specified number of milliseconds * */ nudge(nudge: number): void; updateSettings(settings: FileMp4InputSettingsUpdate): void; /** Pause the MP4 playback. This may not take fully immediate effect, frames already in flight within the Mp4Input workflow will still be emitted */ pause(options?: { quiet?: boolean; }): void; /** Start/resume the MP4 playback */ play(): void; /** Start MP4 playback, pausing once the given offset is reached */ playUntil(offsetMs: number): void; /** Seek to a given point, without starting playback. When the stream is played/resumed, it will start from (about) this offset */ seek(offsetMs: number): void; } /** * @public * Settings for an File Based WAV Input * see: {@link NorskInput.fileWav} */ export interface FileWavInputSettings extends SourceNodeSettings { /** The source name to set in the stream key of the outgoing stream */ sourceName: string; /** Path to the WAV file to read */ fileName: string; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; } /** * @public * see: {@link NorskInput.fileWav} */ export declare class FileWavInputNode extends SourceMediaNode { } /** * @public * Settings for a CMAF ingest input. * Receives fMP4 init and media segments via HTTP PUT/POST. */ export interface CmafIngestInputSettings extends SourceNodeSettings, StreamStatisticsMixin { /** The name of this CMAF ingest endpoint (used in the URL path) */ name: string; /** Called when a new track (representation) connects */ onTrackConnected?: (representationId: string) => void; /** Called when a track (representation) disconnects */ onTrackDisconnected?: (representationId: string) => void; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; /** * When set, each incoming init and media segment is validated against the * C2PA Live Video continuity chain (spec §19.3). Per-segment outcomes are * delivered to `onC2paSegmentVerified`. Reporting-only: media flows * regardless of validation result. */ c2paVerification?: C2paVerificationSettings; /** * Called once per init segment and once per media segment when * {@link CmafIngestInputSettings.c2paVerification} is configured. * `representationId` matches the URL path component pushed by the * publisher. `isInit` distinguishes the init from media segments. */ onC2paSegmentVerified?: (info: { representationId: string; isInit: boolean; outcome: C2paValidationOutcome; }) => void; } /** * @public * A CMAF ingest input node that receives fMP4 segments via HTTP PUT/POST. * * Once created, the ingest endpoint accepts segments at: * - `PUT /cmaf-ingest/{name}/{representationId}/init.mp4` for init segments * - `PUT /cmaf-ingest/{name}/{representationId}/{number}.m4s` for media segments */ export declare class CmafIngestInputNode extends SourceMediaNode { grpcStream: grpc.ClientDuplexStream; initialised: Promise; /** The URL for pushing CMAF segments to this endpoint */ endpointUrl: string; static create(settings: CmafIngestInputSettings, client: MediaClient, unregisterNode: (node: MediaNodeState) => void): Promise; constructor(settings: CmafIngestInputSettings, client: MediaClient, unregisterNode: (node: MediaNodeState) => void); nudge(sourceName: string, programNumber: number, nudge: number): void; } /** * @public * Methods that allow you to ingest media into your application */ /** * @public * Settings for a MoQ Input node * see {@link NorskInput.moq} */ /** * @public * Settings for a MoQ ingest listener that accepts publisher connections. */ export interface MoqInputListenerSettings { /** * Namespace prefix to accept publishers for, as a list of segments * (the on-the-wire MoQT tuple). Any incoming PUBLISH_NAMESPACE whose * tuple BEGINS with these segments is routed to this ingest; * everything else is rejected at the listener pool. Matching is * SEGMENT-AWARE: prefix `["stage", "primary"]` matches publishers * whose tuple begins with `["stage", "primary", ...]` but does NOT * match `["stage", "primaryextra"]`. The * {@link MoqInputSettings.onConnection} callback is invoked per * accepted publisher with the full published namespace tuple. */ namespacePrefix: string[]; /** * QUIC listener port for publisher connections */ quicServerPort?: number; /** * WebTransport listener port for publisher connections */ webTransportPort?: number; /** * TLS certificate file path (required when a port is set) */ quicServerCert?: string; /** * TLS private key file path (required when a port is set) */ quicServerKey?: string; /** * Also accept publishers over the shared per-instance iroh endpoint * (see norsk.system.iroh): the namespace prefix routes on the * endpoint's NodeId, so remote encoders can publish to * `iroh://` with no port, cert or firewall hole. Peers must * be on the endpoint's allow-list. */ iroh?: boolean; /** * Or accept over a DEDICATED iroh identity for this input alone — * its own key, allow-list and relay mode on its own endpoint * (advanced/multi-tenant; most users want `iroh: true`). */ irohDedicated?: IrohDedicatedListenerSettings; } export interface MoqInputSettings extends SourceNodeSettings, StreamStatisticsMixin { /** * The URL of the MoQT relay to connect to (e.g. 'moqt://relay.example.com:4443'). * Omit when using listener mode. */ url?: string; /** * The namespace to subscribe to (client mode only), as a list of * segments (the on-the-wire MoQT tuple). For listener mode, set * `listener.namespacePrefix` instead — incoming publishers are * matched by prefix and identified per-connection via * {@link MoqInputSettings.onConnection}. */ namespace: string[]; /** * Disable verification of remote server's TLS certificate * (for development use ONLY, not for production) */ disableTlsVerify?: boolean; /** * Optional: start a listener for direct publisher connections. * When set, the ingest accepts incoming MoQT publisher connections instead of * (or in addition to) connecting to a relay as a subscriber. */ listener?: MoqInputListenerSettings; /** * Called when a new publisher connects via QUIC or WebTransport * (listener mode only). `publishedNamespace` is the full namespace * tuple the publisher announced, as a list of segments — e.g. for * the namespace `<"stage", "primary">` it's `["stage", "primary"]`. * Return accept with a sourceName, or reject to deny. */ onConnection?: (connectionIndex: number, remoteHost: string, publishedNamespace: string[]) => MoqConnectionResult; /** * Called when a publisher connection status changes (listener mode only) */ onConnectionStatusChange?: (connectionIndex: number, state: string) => void; /** * Called when a PRFT (Producer Reference Time) box is detected in an * incoming CMAF segment. Carries the NTP wall-clock timestamp and * the media decode time from the PRFT box. */ onTimecode?: (ntpTimestamp: number, mediaTime: number) => void; /** * Optional time-domain configuration. When set, the input is placed into a * named coordinator and is timestamp-aligned with all other inputs sharing * the same domain id within this Norsk instance. Omit for the default * (uncoordinated) behaviour. */ timeDomain?: TimeDomain; /** * When set, each incoming init and media segment is validated against the * C2PA Live Video continuity chain (spec §19.3). Per-segment outcomes are * delivered to `onC2paSegmentVerified`. Reporting-only: media flows * regardless of validation result. */ c2paVerification?: C2paVerificationSettings; /** * Pin the MoQT transport draft this ingest negotiates (client mode), instead * of auto-negotiating. Auto lands on the newest draft both ends prefer * (draft-16 for Norsk↔Norsk). Set `"draft18"` to negotiate draft-18, which is * required to activate the joining-FETCH catalog bootstrap. Mirrors * {@link MoqOutputSettings.moqProtocolVersion}. */ moqProtocolVersion?: "auto" | "draft14" | "draft16" | "draft18"; /** * The source name to give the ingested media (client mode). Omit to derive it * from the namespace. Set a distinct name when two MoQ inputs in the same * instance subscribe to the SAME namespace — otherwise they produce identical * stream keys and collide. */ sourceName?: string; /** * Where in the publication media-track subscriptions start (client mode). * - `"nextGroupStart"` (default): join at the next group boundary, so the * first delivered object is a keyframe — clean decode start, latency up * to one group/GOP. * - `"latestObject"`: join mid-group at the very next published object — * lowest latency, but video is undecodable until the next keyframe. * - `"fromStart"`: replay whatever history the publisher retains, then * continue live — for consumers that want the whole publication (e.g. * file-output workflows). */ subscribeFilter?: "nextGroupStart" | "latestObject" | "fromStart"; /** * Called once per init segment and once per media segment when * {@link MoqInputSettings.c2paVerification} is configured. For MoQ inputs, * `representationId` carries the MoQ track name from the underlying CMAF * stream. */ onC2paSegmentVerified?: (info: { representationId: string; isInit: boolean; outcome: C2paValidationOutcome; }) => void; } /** * @public * see: {@link NorskInput.moq} */ export declare class MoqInputNode extends SourceMediaNode { /** * Close a specific publisher connection (listener mode only). */ closeStream(connectionIndex: number): void; } export interface NorskInput { /** Create an RTMP Server to receive RTMP streams into your application * @param settings - Configuration for the RTMP server */ rtmpServer(settings: RtmpServerInputSettings): Promise; /** * Read from a Transport Stream file with realtime playback. * @param settings - Configuration for the file input */ fileTs(settings: FileTsInputSettings): Promise; /** * Stream from a SRT source * @param settings - Configuration for the SRT input */ srt(settings: SrtInputSettings): Promise; /** * Stream from a SRT "raw" elementary stream source * @param settings - Configuration for the SRT input */ srtRaw(settings: SrtRawInputSettings): Promise; /** * Receive media via WebRTC via the WHIP standard. * * Here Norsk acts as the Media Server receiving from a remote WHIP client, to act as the * WHIP client sending to a remote media server see {@link NorskOutput.whip}. For a duplex * connection to a browser peer see {@link NorskDuplex.webRtcBrowser}. * * @param settings - Configuration for the WHIP input */ whip(settings: WhipInputSettings): Promise; /** * Pull an m3u8 HLS media stream and output it into Norsk in realtime */ m3u8Media(settings: M3u8MediaInputSettings): Promise; /** * Pull an HLS *master* (multivariant) playlist and ingest every TS * rendition it enumerates through a single input. All renditions share a * TimeDomain so their timestamps are anchored to a common clock. * * Subtitle (EXT-X-MEDIA TYPE=SUBTITLES) renditions are not consumed here - * use {@link NorskInput.m3u8WebVtt} per subtitle rendition for now. */ m3u8MultiVariant(settings: M3u8MultiVariantInputSettings): Promise; /** * Pull an HLS WebVTT subtitle rendition (the media playlist that an * EXT-X-MEDIA TYPE=SUBTITLES entry of a master playlist references). * Fetches `.vtt` segments and emits a single subtitle output pin. */ m3u8WebVtt(settings: M3u8WebVttInputSettings): Promise; /** * Pull a TAMS flow and output it into Norsk in realtime */ tamsFlow(settings: TamsFlowInputSettings): Promise; /** * Read from a Transport Stream on the network * This can be multicast/unicast or broadcast * @param settings - Configuration for the UDP input */ udpTs(settings: UdpTsInputSettings): Promise; /** * Read from a Transport Stream over TCP. Norsk acts as the TCP client, * connecting out to the configured host/port and reconnecting on failure. * @param settings - Configuration for the TCP input */ tcpTs(settings: TcpTsInputSettings): Promise; /** * Read subtitles from a WebVTT file on disk * @param settings - Configuration for the file input */ fileWebVtt(settings: WebVttFileInputSettings): Promise; /** * Stream subtitles in e.g. WebVTT format via API calls. Chunks of cues can be sent * in an ongoing timeline (as if streaming a fragmented WebVTT file), or a stream of * timestamped words/fragments. * @param settings - Configuration for the stream input */ streamSubtitles(settings: StreamSubtitlesInputSettings): Promise; /** * Read an image from a file. Various image formats are supported, see the * documentation for {@link FileImageInputSettings} for more details. * @param settings - Configuration for the file input * * The image will then be provided into Norsk as a video at 25fps for use * in other operations */ fileImage(settings: FileImageInputSettings): Promise; /** * Read a MP4 (fragmented or not) from a file with realtime playback. * This will not play frames that are written to the file after the node * starts. * @param settings - Configuration for the file input */ fileMp4(settings: FileMp4InputSettings): Promise; /** * Read a WAV file with PCM audio with realtime playback. * @param settings - Configuration for the file input */ fileWav(settings: FileWavInputSettings): Promise; /** * Stream from a remote RTP source * * Note that MPEG-TS sources encapsulated in RTP should use the {@link NorskInput.udpTs} input with appropriate config. * @param settings - Configuration for the RTP input */ rtp(settings: RtpInputSettings): Promise; /** * Generate a test video card with a configurable pattern. * @param settings - Configuration for the video test card */ videoTestCard(settings: VideoTestcardGeneratorSettings): Promise; /** * Generate a test audio signal with a configurable waveform. * @param settings - Configuration for the audio signal */ audioSignal(settings: AudioSignalGeneratorSettings): Promise; /** * Generates a video source by rendering an HTML page * @param settings - Settings for the web page */ browser(settings: BrowserInputSettings): Promise; /** * SDI/HDMI Input using a BlackMagic DeckLink card. * The available cards on the machine can be enumerated using the {@link NorskSystem.hardwareInfo} API. * * Multiple cards and both SDI and HDMI inputs are supported, with all DeckLink-supported * input resolutions and framerates are supported. The capture format is currently 8-bit only, * but 10-bit captures will be supported soon. All supported audio channels can be captured. * At present, additional data such as closed-captions and HDR metadata is not captured. * @param settings - Settings for the SDI capture */ deckLink(settings: DeckLinkInputSettings): Promise; /** * SDI Input using Deltacast SDI capture cards. * The available cards on the machine can be enumerated using the * `HardwareInfo` rpc. * * Multiple cards are supported, with all * Deltacast-supported input resolutions and framerates are supported. The * capture format is currently 8-bit only. All supported audio channels can be captured. At present, * additional data such as closed-captions and HDR metadata is not captured. */ deltaCast(settings: DeltacastInputSettings): Promise; /** * NDI Input. Available NDI sources can be enumerated using the `ndiDiscovery` call * @param settings - Settings for the NDI capture */ ndi(settings: NdiInputSettings): Promise; /** * Receive CMAF fMP4 segments via HTTP PUT/POST. * @param settings - Configuration for the CMAF ingest endpoint */ cmafIngest(settings: CmafIngestInputSettings): Promise; /** * Read media from an MXL (Media eXchange Layer) shared memory domain. * Produces v210 video and float32 planar audio. * @param settings - Configuration for the MXL input */ mxl(settings: MxlInputSettings): Promise; /** * Receive input from a MoQ (Media over QUIC) source. * Connects to a MoQT relay and subscribes to tracks in the specified namespace. * @param settings - Configuration for the MoQ input */ moq(settings: MoqInputSettings): Promise; } export {}; //# sourceMappingURL=input.d.ts.map