import * as grpc from "@grpc/grpc-js"; import { MediaClient } from "@norskvideo/norsk-api/lib/media_grpc_pb"; import { Hardware as HardwarePB, NdiDiscoveryConfiguration, NdiDiscoveryEvent } from "@norskvideo/norsk-api/lib/media_pb"; import { Empty } from "@bufbuild/protobuf"; import * as util from "util"; import { CpuTopology, DeckLinkCard, MA35DCard, fromCpuTopology, fromDeckLinkCard, fromMA35DCard } from "./types"; import { exhaustiveCheck, provideFull } from "./shared/utils"; import { registerNonNodeGrpc } from "./media_nodes/common"; /** * @public * */ /** * @public */ export interface HardwareInfo { cpuTopology: CpuTopology; systemMemory: number; deckLinkCards: DeckLinkCard[]; ma35dCards: MA35DCard[]; } /** @internal */ export async function hardwareInfo(client: MediaClient): Promise { const fn = util.promisify(client.hardwareInfo).bind(client); return fn(new Empty()).then((info: HardwarePB) => { return { cpuTopology: fromCpuTopology(info.cpuTopology), systemMemory: info.systemMemory, deckLinkCards: info.deckLinkCards.map(fromDeckLinkCard), ma35dCards: info.ma35dCards.map(fromMA35DCard) }; }); } /** * @public */ export interface NdiSource { name: string; url: string; } /** * @public */ export interface NdiDiscoverySettings { showLocalSources: boolean; groups?: string; extraIps?: string; cb: (sources: NdiSource[]) => void; onClose?: (() => Promise) | (() => void), onError?: (error: Error) => void; } /** * @public */ export class NdiDiscovery { /** @internal */ client: MediaClient; /** @internal */ grpcStream: grpc.ClientReadableStream; /** @internal */ initialised: Promise; /** @internal */ public static async create( settings: NdiDiscoverySettings, client: MediaClient) { const ndi = new NdiDiscovery(settings, client); await ndi.initialised; return ndi; } /** @internal */ constructor(settings: NdiDiscoverySettings, client: MediaClient) { this.client = client; this.grpcStream = this.client.ndiDiscovery(provideFull(NdiDiscoveryConfiguration, { showLocalSources: settings.showLocalSources, groups: settings.groups === undefined ? "" : settings.groups, extraIps: settings.extraIps=== undefined ? "" : settings.extraIps, })); this.initialised = new Promise((resolve, reject) => { this.grpcStream.on("data", (data: NdiDiscoveryEvent) => { const messageCase = data.message.case; switch (messageCase) { case undefined: break; case "initialised": resolve(); break; case "sources": settings.cb(data.message.value.sources); break; default: exhaustiveCheck(messageCase); } }); registerNonNodeGrpc(this.grpcStream, "NDI Discovery", reject, settings.onClose, settings.onError); }); } public close() { this.grpcStream.destroy(); } } /** * @public * Methods that allow you query the features of the system that Norsk is running in */ export interface NorskSystem { hardwareInfo(): Promise; ndiDiscovery(settings: NdiDiscoverySettings): Promise }