/// import * as grpc from "@grpc/grpc-js"; import { MediaClient as MediaClientPB } from "@norskvideo/norsk-api/lib/media_grpc_pb"; import EventEmitter from "events"; /** @public */ export type MediaClient = { media: MediaClientPB; subscriptions: grpc.ClientDuplexStream; }; import { StreamStatisticsSampling, GopStructure, SubscriptionChannelMessage, SubscriptionChannelResponse } from "@norskvideo/norsk-api/lib/media_pb"; import { ListValue, Struct, Value } from "@norskvideo/norsk-api/lib/shared/error_pb"; import { Nullable } from "typescript-nullable"; import { StreamKey, MediaNodeId, StreamMetadata, Context, MultiStreamStatistics, SubscriptionError } from "./types"; export * from "../shared/utils"; import { PlainMessage } from "@bufbuild/protobuf"; /** * @public * Settings common to all media nodes */ export interface NodeSettings { /** * Media Node identifier. If one is not specified, a random identifier will be generated. */ id?: string; /** * Called with any errors from the Node. * * This includes both errors which will cause the node to exit, and those that do not * but may e.g. indicate a connection has failed. */ onError?: (error: Error) => void; /** * Called when the Node closes. * * This may be by request, because the node naturally exits or an error has occurred. See `onError` * to be notified of errors which may lead to the node closing. */ onClose?: (() => Promise) | (() => void); /** * Callback to synchronously perform an action when node creation is complete * (e.g. subscribe a downstream node before the first context/frame might arrive) */ onCreate?: (node: T) => void; } /** @public */ export interface SourceNodeSettings extends NodeSettings { onOutboundContextChange?: (streams: StreamMetadata[]) => Promise; } /** @public */ export interface SinkNodeSettings extends NodeSettings { onSubscriptionError?: (error: SubscriptionError) => void; } /** @public */ export interface StreamStatisticsMixin { /** * Sampling rates for stream stats, in seconds */ statsSampling?: PlainMessage; /** * Called at periodic intervals when stream statistics are ready. * @eventProperty */ onStreamStatistics?: ( /** The stats */ stats: MultiStreamStatistics) => void; onGopStructure?: (structure: GopStructure) => void; } /** @public */ export type EventMap = { [key: string]: (arg: any) => void; }; /** @public */ export type MediaNodeStateEvents = { close: (id: string) => void; }; /** @public */ export declare class MediaNodeState { id: MediaNodeId | undefined; closed: boolean; events: EventEmitter; protected emit(name: E, arg: Parameters[0]): void; on(name: E, listener: Events[E]): void; off(name: E, listener: Events[E]): void; constructor(client: MediaClient); /** @public */ close(): Promise; } /** @public */ export type ReceiveFromAddress = { source: SubscriptionSource; sourceSelector: (streams: StreamMetadata[]) => PinToKey; }; /** @public */ export type ReceiveFromAddressAuto = { source: SubscriptionSource; sourceSelector: (streams: StreamMetadata[]) => StreamKey[]; }; /** @public */ export type PinToKey = Nullable>>; /** @public */ export interface SubscribeDestination { id?: string; sourceContextChange(responseCallback: (error?: SubscriptionError) => void): Promise; on?: (e: "close", a: () => void) => void; off?: (e: "close", a: () => void) => void; } export interface SubscriptionSource { id?: string; outputStreams: StreamMetadata[]; registerForContextChange: (subscriber: SubscribeDestination) => void; unregisterForContextChange: (subscriber: SubscribeDestination) => void; } /** @public */ export type SourceMediaNodeEvents = { outboundContextChange: (streams: StreamMetadata[]) => void; } & MediaNodeStateEvents; /** @public */ export declare class SourceMediaNode extends MediaNodeState implements SubscriptionSource { outputStreams: StreamMetadata[]; registerForContextChange(subscriber: SubscribeDestination): void; unregisterForContextChange(subscriber: SubscribeDestination): void; } /** * @public * Determines what to do with an incoming context * * - true/accept: Allow the incoming context through, and any subsequent/queued data that belongs to it * - false/deny: Deny the incoming context, if no context has been accepted, then queue data until one is * - accept_and_terminate: Allow the incoming context, then deny further data, flush and shut down the node * this is useful for cleanly terminating outputs when the context is empty * - deny_and_queue: Deny the incoming context, and revert to the original queueing behaviour as if no context has been accepted * this is useful when switching from one full context to another, avoiding any "in-between" * - deny_and_drop: Deny the incoming context, drop any currently queued data, and drop any further data that might be received * this is useful if you have a lot of setup on start-up and would prefer not to queue data while waiting for that to take place * */ export type SubscriptionValidationResponse = true | false | "accept" | "deny" | "accept_and_terminate" | "deny_and_queue" | "deny_and_drop"; /** @public */ export declare class SinkMediaNode extends MediaNodeState implements SubscribeDestination { permissiveSubscriptionValidation(_context: Context): SubscriptionValidationResponse; restrictiveSubscriptionValidation(context: Context): SubscriptionValidationResponse; /** Subscribe to the given sources. * * This version of the function call accepts the target pins of an output * and is suitable for advanced use where a node is capable of subscribing to * multiple video streams and provides a means of distinguishing them via pins * discarding any existing subscriptions. * * @param done - will be called with no arguments if the subscription succeeds, * or an error if it failed. This error indicates the specific reason it * failed, so you can take appropriate actions in response. It will be called * before the `subscribedStreamsChangedFn` or `subscribeErrorFn` callbacks * provided in the config for the node. * * Errors are also logged to the debug log. */ subscribeToPins(sources: ReceiveFromAddress[], validation?: (context: Context) => SubscriptionValidationResponse, done?: (error?: SubscriptionError) => void): void; sourceContextChange(responseCallback: (error?: SubscriptionError) => void): Promise; finalise(): void; } /** @public */ export declare class AutoSinkMediaNode extends SinkMediaNode { /** Subscribe to the given sources. * * This version of subscribe simply requires a list of stream keys to be * returned from each selector, and the server will automatically * assign each stream to the appropriate pin on the sink node. * This is the appropriate method for most cases. * * @param done - will be called with no arguments if the subscription succeeds, * or an error if it failed. This error indicates the specific reason it * failed, so you can take appropriate actions in response. It will be called * before the `subscribedStreamsChangedFn` or `subscribeErrorFn` callbacks * provided in the config for the node. * * Errors are also logged to the debug log. */ subscribe(sources: ReceiveFromAddressAuto[], validation?: (context: Context) => SubscriptionValidationResponse, done?: (error?: SubscriptionError) => void): void; } export declare function valueToNative(value: Value): unknown; export declare function nativeToValue(input: unknown): Value; export declare function nativeToStruct(input: Record): Struct; export declare function nativeToListValue(input: unknown[]): ListValue; //# sourceMappingURL=common.d.ts.map