import type { Logger } from 'zapo-js'; import { type BinaryNode } from 'zapo-js/transport'; import { type WaCallMediaEvent, type WaCallMediaMessage, type WaCallReaction } from '@zapo-js/voip-media'; import { type PeerScreenShare } from '../signaling/screen-share.js'; import { type WaVideoUpgradeResult } from '../signaling/signaling.js'; import { type WaVoipSettings } from '../signaling/voip-settings.js'; import { EndCallReason, type InboundVideoFrame, type InboundVideoRtpPacket, type PeerVideoStateChange, type WaVoipDeps } from '../types.js'; import { type CallInfo } from './call-state.js'; import type { WaCallMediaLink, WaCallMediaLinkEvents } from './media-link.js'; export interface WaCallMediaSessionDelegate { emitState(call: CallInfo): void; emitIncoming(call: CallInfo): void; emitEnded(call: CallInfo): void; emitPeerMute(call: CallInfo, muted: boolean): void; emitInboundAudio(call: CallInfo, data: Float32Array): void; emitInboundVideoRtp(call: CallInfo, packet: InboundVideoRtpPacket): void; emitInboundVideo(call: CallInfo, frame: InboundVideoFrame): void; emitScreenShare(call: CallInfo, share: PeerScreenShare): void; emitPeerVideoState(call: CallInfo, change: PeerVideoStateChange): void; emitOutboundAudioFinished(call: CallInfo): void; emitHandRaise(call: CallInfo, participantJid: string, raised: boolean): void; /** One in-band emoji reaction, deduplicated: the sender repeats it, this fires once. */ emitCallReaction?(call: CallInfo, reaction: WaCallReaction): void; /** A change to the media plan, for a host elsewhere to apply; remote media only. */ emitMediaPlan?(call: CallInfo, message: WaCallMediaMessage): void; /** Ends the call through its owner, for a session that has to end itself. */ endCall(call: CallInfo, reason: EndCallReason): void; } export interface WaCallMediaSessionOptions { readonly deps: WaVoipDeps; readonly logger: Logger; readonly info: CallInfo; readonly delegate: WaCallMediaSessionDelegate; /** Builds the link to wherever this call's media runs, in this process or elsewhere. */ readonly createMediaLink: (events: WaCallMediaLinkEvents) => WaCallMediaLink; /** Monotonic clock the video hold is timed on, in ms; `performance.now` by default. */ readonly now?: () => number; } /** * The signaling of one call, and the source of its media plan: what the stanzas teach the * media is derived into the plan and published on the media link. */ export declare class WaCallMediaSession { readonly info: CallInfo; private readonly deps; private readonly logger; private readonly delegate; private readonly media; private initialTransportSent; private outgoingPreacceptSent; /** Relays our own `` already named; bounded by the relays the server lists. */ private readonly announcedRelayNames; /** The peer's last `latency` per relay name, as sent; kept for the relay election, unused yet. */ private readonly peerRelayLatencies; private peerRelayLatencyReports; /** The SSRC lists of the plan as last derived; published whole as `ssrcs` on any change. */ private selfStreamSsrcs; private peerAudioSsrc; private peerStreamSsrcs; private peerVideoStreamSsrcs; /** * App-data SSRCs of the peer's devices: inbound app data is recognized by SSRC, * never by payload type, which nothing negotiates. */ private readonly peerAppDataSsrcs; /** Bumped when the SRTP keys change, so the media rebuilds its contexts only then. */ private keyEpoch; private lastKeys; /** Last value published per plan section, so an unchanged one is not sent again. */ private readonly publishedSections; /** * Our own device jid, as the SSRC derivation takes it: an upgraded call derives a * video SSRC long after the jid was resolved. */ private selfDeviceJid; /** Whether {@link ensureVideoReceivePath} ran; a call negotiated as video never sets it. */ private videoReceivePathOpened; /** * Whether an accepted upgrade opened the local video sender on a call negotiated as * audio. Until it does the media drops every video frame: no video RTP leaves before * the peer has accepted. */ private videoSendPathOpened; /** * Holds our video until the peer can take it: after an accepted peer upgrade, and from the * accept on a call born as video. Published as `video.sendHeld`. */ private readonly peerVideoReadyGate; /** Whether the one post-active `` declaration has gone out. */ private initialMuteAnnounced; /** * Our counter behind `transaction-id` on the `