From f0d659d2600ff0ed3618eae09233663b53014beb Mon Sep 17 00:00:00 2001 From: Kevin Venalainen Date: Wed, 12 Jun 2024 10:52:02 -0700 Subject: [PATCH] Add onRtcSender and onRtcReceiver callbacks --- src/Consumer.ts | 3 ++- src/Producer.ts | 3 ++- src/Transport.ts | 7 ++++++- src/handlers/Chrome111.ts | 22 ++++++++++++++++++++++ src/handlers/HandlerInterface.ts | 14 ++++++++++++++ 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/Consumer.ts b/src/Consumer.ts index eb0a901a..227ffeba 100644 --- a/src/Consumer.ts +++ b/src/Consumer.ts @@ -2,7 +2,7 @@ import { Logger } from './Logger'; import { EnhancedEventEmitter } from './EnhancedEventEmitter'; import { InvalidStateError } from './errors'; import { MediaKind, RtpParameters } from './RtpParameters'; -import { AppData } from './types'; +import { AppData, ReceiverCallback } from './types'; const logger = new Logger('Consumer'); @@ -12,6 +12,7 @@ export type ConsumerOptions = { kind?: 'audio' | 'video'; rtpParameters: RtpParameters; streamId?: string; + onRtpReceiver?: ReceiverCallback; appData?: ConsumerAppData; }; diff --git a/src/Producer.ts b/src/Producer.ts index 4be5666a..962ac189 100644 --- a/src/Producer.ts +++ b/src/Producer.ts @@ -7,7 +7,7 @@ import { RtpParameters, RtpEncodingParameters, } from './RtpParameters'; -import { AppData } from './types'; +import { AppData, SenderCallback } from './types'; const logger = new Logger('Producer'); @@ -19,6 +19,7 @@ export type ProducerOptions = { stopTracks?: boolean; disableTrackOnPause?: boolean; zeroRtpOnPause?: boolean; + onRtpSender?: SenderCallback; appData?: ProducerAppData; }; diff --git a/src/Transport.ts b/src/Transport.ts index 49fc14aa..9fc1ff77 100644 --- a/src/Transport.ts +++ b/src/Transport.ts @@ -490,6 +490,7 @@ export class Transport< stopTracks = true, disableTrackOnPause = true, zeroRtpOnPause = false, + onRtpSender, appData = {} as ProducerAppData, }: ProducerOptions = {}): Promise< Producer @@ -570,6 +571,7 @@ export class Transport< encodings: normalizedEncodings, codecOptions, codec, + onRtpSender, }); try { @@ -639,6 +641,7 @@ export class Transport< kind, rtpParameters, streamId, + onRtpReceiver, appData = {} as ConsumerAppData, }: ConsumerOptions): Promise> { logger.debug('consume()'); @@ -681,6 +684,7 @@ export class Transport< kind, rtpParameters: clonedRtpParameters, streamId, + onRtpReceiver, appData, }); @@ -876,13 +880,14 @@ export class Transport< const optionsList: HandlerReceiveOptions[] = []; for (const task of pendingConsumerTasks) { - const { id, kind, rtpParameters, streamId } = task.consumerOptions; + const { id, kind, rtpParameters, streamId, onRtpReceiver } = task.consumerOptions; optionsList.push({ trackId: id!, kind: kind as MediaKind, rtpParameters, streamId, + onRtpReceiver, }); } diff --git a/src/handlers/Chrome111.ts b/src/handlers/Chrome111.ts index 186a5552..d8c4038f 100644 --- a/src/handlers/Chrome111.ts +++ b/src/handlers/Chrome111.ts @@ -321,6 +321,7 @@ export class Chrome111 extends HandlerInterface { encodings, codecOptions, codec, + onRtpSender, }: HandlerSendOptions): Promise { this.assertNotClosed(); this.assertSendDirection(); @@ -378,6 +379,11 @@ export class Chrome111 extends HandlerInterface { streams: [this._sendStream], sendEncodings: encodings, }); + + if (onRtpSender) { + onRtpSender(transceiver.sender); + } + const offer = await this._pc.createOffer(); let localSdpObject = sdpTransform.parse(offer.sdp); @@ -826,6 +832,22 @@ export class Chrome111 extends HandlerInterface { await this._pc.setRemoteDescription(offer); + for (const options of optionsList) { + const { trackId, onRtpReceiver } = options; + + if (onRtpReceiver) { + const localId = mapLocalId.get(trackId); + const transceiver = this._pc.getTransceivers() + .find((t: RTCRtpTransceiver) => t.mid === localId); + + if (!transceiver) { + throw new Error('transceiver not found'); + } + + onRtpReceiver(transceiver.receiver); + } + } + let answer = await this._pc.createAnswer(); const localSdpObject = sdpTransform.parse(answer.sdp); diff --git a/src/handlers/HandlerInterface.ts b/src/handlers/HandlerInterface.ts index 8dd7dbf1..62062f2b 100644 --- a/src/handlers/HandlerInterface.ts +++ b/src/handlers/HandlerInterface.ts @@ -34,11 +34,18 @@ export type HandlerRunOptions = { extendedRtpCapabilities: any; }; +/* + * Invoked synchronously immediately after a new RTCRtpSender is created. + * This allows for creating encoded streams in chromium browsers. + */ +export type SenderCallback = (sender: RTCRtpSender) => void; + export type HandlerSendOptions = { track: MediaStreamTrack; encodings?: RtpEncodingParameters[]; codecOptions?: ProducerCodecOptions; codec?: RtpCodecCapability; + onRtpSender?: SenderCallback; }; export type HandlerSendResult = { @@ -47,6 +54,12 @@ export type HandlerSendResult = { rtpSender?: RTCRtpSender; }; +/* + * Invoked synchronously immediately after a new RTCRtpReceiver is created. + * This allows for creating encoded streams in chromium browsers. + */ +export type ReceiverCallback = (receiver: RTCRtpReceiver) => void; + export type HandlerReceiveOptions = { trackId: string; kind: 'audio' | 'video'; @@ -58,6 +71,7 @@ export type HandlerReceiveOptions = { * can just synchronize up to one audio stream with one video stream. */ streamId?: string; + onRtpReceiver?: ReceiverCallback; }; export type HandlerReceiveResult = {