Skip to content

Commit

Permalink
Allow create encoded streams (#301)
Browse files Browse the repository at this point in the history
Co-authored-by: Kevin Venalainen <kevin.venalainen@around.co>
  • Loading branch information
ibc and kjvenalainen authored Jun 13, 2024
1 parent 921eb1d commit 9baf645
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/Consumer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@ export type ConsumerOptions<ConsumerAppData extends AppData = AppData> = {
kind?: 'audio' | 'video';
rtpParameters: RtpParameters;
streamId?: string;
onRtpReceiver?: OnRtpReceiverCallback;
appData?: ConsumerAppData;
};

/**
* Invoked synchronously immediately after a new RTCRtpReceiver is created.
* This allows for creating encoded streams in chromium browsers.
*/
export type OnRtpReceiverCallback = (rtpReceiver: RTCRtpReceiver) => void;

export type ConsumerEvents = {
transportclose: [];
trackended: [];
Expand Down
7 changes: 7 additions & 0 deletions src/Producer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,16 @@ export type ProducerOptions<ProducerAppData extends AppData = AppData> = {
stopTracks?: boolean;
disableTrackOnPause?: boolean;
zeroRtpOnPause?: boolean;
onRtpSender?: OnRtpSenderCallback;
appData?: ProducerAppData;
};

/**
* Invoked synchronously immediately after a new RTCRtpSender is created.
* This allows for creating encoded streams in chromium browsers.
*/
export type OnRtpSenderCallback = (rtpSender: RTCRtpSender) => void;

// https://mediasoup.org/documentation/v3/mediasoup-client/api/#ProducerCodecOptions
export type ProducerCodecOptions = {
opusStereo?: boolean;
Expand Down
8 changes: 7 additions & 1 deletion src/Transport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ export class Transport<
stopTracks = true,
disableTrackOnPause = true,
zeroRtpOnPause = false,
onRtpSender,
appData = {} as ProducerAppData,
}: ProducerOptions<ProducerAppData> = {}): Promise<
Producer<ProducerAppData>
Expand Down Expand Up @@ -570,6 +571,7 @@ export class Transport<
encodings: normalizedEncodings,
codecOptions,
codec,
onRtpSender,
});

try {
Expand Down Expand Up @@ -639,6 +641,7 @@ export class Transport<
kind,
rtpParameters,
streamId,
onRtpReceiver,
appData = {} as ConsumerAppData,
}: ConsumerOptions<ConsumerAppData>): Promise<Consumer<ConsumerAppData>> {
logger.debug('consume()');
Expand Down Expand Up @@ -681,6 +684,7 @@ export class Transport<
kind,
rtpParameters: clonedRtpParameters,
streamId,
onRtpReceiver,
appData,
});

Expand Down Expand Up @@ -876,13 +880,15 @@ 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,
});
}

Expand Down
23 changes: 23 additions & 0 deletions src/handlers/Chrome111.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ export class Chrome111 extends HandlerInterface {
encodings,
codecOptions,
codec,
onRtpSender,
}: HandlerSendOptions): Promise<HandlerSendResult> {
this.assertNotClosed();
this.assertSendDirection();
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -826,6 +832,23 @@ 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);

Expand Down
23 changes: 23 additions & 0 deletions src/handlers/Firefox120.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ export class Firefox120 extends HandlerInterface {
encodings,
codecOptions,
codec,
onRtpSender,
}: HandlerSendOptions): Promise<HandlerSendResult> {
this.assertNotClosed();
this.assertSendDirection();
Expand Down Expand Up @@ -384,6 +385,11 @@ export class Firefox120 extends HandlerInterface {
streams: [this._sendStream],
sendEncodings: encodings,
});

if (onRtpSender) {
onRtpSender(transceiver.sender);
}

const offer = await this._pc.createOffer();
let localSdpObject = sdpTransform.parse(offer.sdp);

Expand Down Expand Up @@ -851,6 +857,23 @@ export class Firefox120 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);

Expand Down
5 changes: 4 additions & 1 deletion src/handlers/HandlerInterface.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { EnhancedEventEmitter } from '../EnhancedEventEmitter';
import { ProducerCodecOptions } from '../Producer';
import {
IceParameters,
IceCandidate,
DtlsParameters,
IceGatheringState,
ConnectionState,
} from '../Transport';
import { ProducerCodecOptions, OnRtpSenderCallback } from '../Producer';
import { OnRtpReceiverCallback } from '../Consumer';
import {
RtpCapabilities,
RtpCodecCapability,
Expand Down Expand Up @@ -39,6 +40,7 @@ export type HandlerSendOptions = {
encodings?: RtpEncodingParameters[];
codecOptions?: ProducerCodecOptions;
codec?: RtpCodecCapability;
onRtpSender?: OnRtpSenderCallback;
};

export type HandlerSendResult = {
Expand All @@ -58,6 +60,7 @@ export type HandlerReceiveOptions = {
* can just synchronize up to one audio stream with one video stream.
*/
streamId?: string;
onRtpReceiver?: OnRtpReceiverCallback;
};

export type HandlerReceiveResult = {
Expand Down
23 changes: 23 additions & 0 deletions src/handlers/ReactNativeUnifiedPlan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ export class ReactNativeUnifiedPlan extends HandlerInterface {
encodings,
codecOptions,
codec,
onRtpSender,
}: HandlerSendOptions): Promise<HandlerSendResult> {
this.assertNotClosed();
this.assertSendDirection();
Expand Down Expand Up @@ -368,6 +369,11 @@ export class ReactNativeUnifiedPlan extends HandlerInterface {
streams: [this._sendStream],
sendEncodings: encodings,
});

if (onRtpSender) {
onRtpSender(transceiver.sender);
}

let offer = await this._pc.createOffer();
let localSdpObject = sdpTransform.parse(offer.sdp);
let offerMediaObject;
Expand Down Expand Up @@ -884,6 +890,23 @@ export class ReactNativeUnifiedPlan 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);

Expand Down
23 changes: 23 additions & 0 deletions src/handlers/Safari12.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ export class Safari12 extends HandlerInterface {
encodings,
codecOptions,
codec,
onRtpSender,
}: HandlerSendOptions): Promise<HandlerSendResult> {
this.assertNotClosed();
this.assertSendDirection();
Expand Down Expand Up @@ -350,6 +351,11 @@ export class Safari12 extends HandlerInterface {
direction: 'sendonly',
streams: [this._sendStream],
});

if (onRtpSender) {
onRtpSender(transceiver.sender);
}

let offer = await this._pc.createOffer();
let localSdpObject = sdpTransform.parse(offer.sdp);
let offerMediaObject;
Expand Down Expand Up @@ -822,6 +828,23 @@ export class Safari12 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);

Expand Down

0 comments on commit 9baf645

Please sign in to comment.