///
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