Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Consumer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import type { AppData } from './types';
const logger = new Logger('Consumer');

export type ConsumerOptions<ConsumerAppData extends AppData = AppData> = {
id?: string;
producerId?: string;
kind?: 'audio' | 'video';
id: string;
producerId: string;
kind: 'audio' | 'video';
rtpParameters: RtpParameters;
streamId?: string;
onRtpReceiver?: OnRtpReceiverCallback;
Expand Down
4 changes: 2 additions & 2 deletions src/DataConsumer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const logger = new Logger('DataConsumer');

export type DataConsumerOptions<DataConsumerAppData extends AppData = AppData> =
{
id?: string;
dataProducerId?: string;
id: string;
dataProducerId: string;
sctpStreamParameters: SctpStreamParameters;
label?: string;
protocol?: string;
Expand Down
1 change: 1 addition & 0 deletions src/Producer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const logger = new Logger('Producer');

export type ProducerOptions<ProducerAppData extends AppData = AppData> = {
track?: MediaStreamTrack;
stream?: MediaStream;
encodings?: RtpEncodingParameters[];
codecOptions?: ProducerCodecOptions;
headerExtensionOptions?: ProducerHeaderExtensionOptions;
Expand Down
6 changes: 6 additions & 0 deletions src/RtpParameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ export type RtpParameters = {
* Parameters used for RTCP.
*/
rtcp?: RtcpParameters;
/**
* MSID (WebRTC MediaStream Identification).
*
* @see https://datatracker.ietf.org/doc/html/rfc8830
*/
msid?: string;
};

/**
Expand Down
10 changes: 6 additions & 4 deletions src/Transport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ export class Transport<
*/
async produce<ProducerAppData extends AppData = AppData>({
track,
stream,
encodings,
codecOptions,
headerExtensionOptions,
Expand Down Expand Up @@ -587,6 +588,7 @@ export class Transport<
const { localId, rtpParameters, rtpSender } =
await this._handler.send({
track,
stream,
encodings: normalizedEncodings,
codecOptions,
headerExtensionOptions,
Expand Down Expand Up @@ -902,8 +904,8 @@ export class Transport<
task.consumerOptions;

optionsList.push({
trackId: id!,
kind: kind!,
trackId: id,
kind: kind,
rtpParameters,
streamId,
onRtpReceiver,
Expand All @@ -920,9 +922,9 @@ export class Transport<
task.consumerOptions;
const { localId, rtpReceiver, track } = result;
const consumer: Consumer<ConsumerAppData> = new Consumer({
id: id!,
id,
localId,
producerId: producerId!,
producerId,
rtpReceiver,
track,
rtpParameters,
Expand Down
23 changes: 19 additions & 4 deletions src/handlers/Chrome111.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class Chrome111
// Map of RTCTransceivers indexed by MID.
private readonly _mapMidTransceiver: Map<string, RTCRtpTransceiver> =
new Map();
// Local stream for sending.
// Default local stream for sending if no stream is given.
private readonly _sendStream = new MediaStream();
// Whether a DataChannel m=application section has been created.
private _hasDataChannelMediaSection = false;
Expand Down Expand Up @@ -336,6 +336,7 @@ export class Chrome111

async send({
track,
stream,
encodings,
codecOptions,
headerExtensionOptions,
Expand All @@ -345,7 +346,12 @@ export class Chrome111
this.assertNotClosed();
this.assertSendDirection();

logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);
logger.debug(
'send() [kind:%s, track.id:%s, stream.id:%s]',
track.kind,
track.id,
stream?.id
);

if (encodings && encodings.length > 1) {
// Set rid and verify scalabilityMode in each encoding.
Expand Down Expand Up @@ -374,7 +380,7 @@ export class Chrome111
const mediaSectionIdx = this._remoteSdp.getNextMediaSectionIdx();
const transceiver = this._pc.addTransceiver(track, {
direction: 'sendonly',
streams: [this._sendStream],
streams: [stream ?? this._sendStream],
sendEncodings: encodings,
});

Expand Down Expand Up @@ -481,6 +487,9 @@ export class Chrome111
offerMediaObject,
});

// Set msid.
sendingRtpParameters.msid = offerMediaObject.msid;

// Set RTP encodings by parsing the SDP offer if no encodings are given.
if (!encodings) {
sendingRtpParameters.encodings = sdpUnifiedPlanUtils.getRtpEncodings({
Expand Down Expand Up @@ -905,11 +914,17 @@ export class Chrome111

mapLocalId.set(trackId, localId);

// We ignore MSID `trackId` when consuming and always us our computed
// `trackId` which matches the `consumer.id`.
const { msidStreamId } = ortcUtils.getMsidStreamIdAndTrackId(
rtpParameters.msid
);

this._remoteSdp.receive({
mid: localId,
kind,
offerRtpParameters: rtpParameters,
streamId: streamId ?? rtpParameters.rtcp!.cname!,
streamId: streamId ?? msidStreamId ?? rtpParameters.rtcp?.cname ?? '-',
trackId,
});
}
Expand Down
12 changes: 9 additions & 3 deletions src/handlers/Chrome74.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class Chrome74
// Map of RTCTransceivers indexed by MID.
private readonly _mapMidTransceiver: Map<string, RTCRtpTransceiver> =
new Map();
// Local stream for sending.
// Default local stream for sending if no stream is given.
private readonly _sendStream = new MediaStream();
// Whether a DataChannel m=application section has been created.
private _hasDataChannelMediaSection = false;
Expand Down Expand Up @@ -333,6 +333,7 @@ export class Chrome74

async send({
track,
stream,
encodings,
codecOptions,
headerExtensionOptions,
Expand All @@ -341,7 +342,12 @@ export class Chrome74
this.assertNotClosed();
this.assertSendDirection();

logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);
logger.debug(
'send() [kind:%s, track.id:%s, stream.id:%s]',
track.kind,
track.id,
stream?.id
);

if (encodings && encodings.length > 1) {
encodings.forEach((encoding: RtpEncodingParameters, idx: number) => {
Expand All @@ -352,7 +358,7 @@ export class Chrome74
const mediaSectionIdx = this._remoteSdp.getNextMediaSectionIdx();
const transceiver = this._pc.addTransceiver(track, {
direction: 'sendonly',
streams: [this._sendStream],
streams: [stream ?? this._sendStream],
sendEncodings: encodings,
});
let offer = await this._pc.createOffer();
Expand Down
4 changes: 3 additions & 1 deletion src/handlers/FakeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export class FakeHandler

async send(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
{ track, encodings, codecOptions, codec }: HandlerSendOptions
{ track, stream, encodings, codecOptions, codec }: HandlerSendOptions
): Promise<HandlerSendResult> {
this.assertNotClosed();

Expand Down Expand Up @@ -214,6 +214,8 @@ export class FakeHandler

sendingRtpParameters.mid = `mid-${utils.generateRandomNumber()}`;

sendingRtpParameters.msid = `${stream?.id ?? '-'} ${track.id}`;

if (!encodings) {
encodings = [{}];
}
Expand Down
12 changes: 9 additions & 3 deletions src/handlers/Firefox120.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class Firefox120
// Map of RTCTransceivers indexed by MID.
private readonly _mapMidTransceiver: Map<string, RTCRtpTransceiver> =
new Map();
// Local stream for sending.
// Default local stream for sending if no stream is given.
private readonly _sendStream = new MediaStream();
// Whether a DataChannel m=application section has been created.
private _hasDataChannelMediaSection = false;
Expand Down Expand Up @@ -336,6 +336,7 @@ export class Firefox120

async send({
track,
stream,
encodings,
codecOptions,
codec,
Expand All @@ -344,7 +345,12 @@ export class Firefox120
this.assertNotClosed();
this.assertSendDirection();

logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);
logger.debug(
'send() [kind:%s, track.id:%s, stream.id:%s]',
track.kind,
track.id,
stream?.id
);

if (encodings && encodings.length > 1) {
encodings.forEach((encoding: RtpEncodingParameters, idx: number) => {
Expand All @@ -360,7 +366,7 @@ export class Firefox120

const transceiver = this._pc.addTransceiver(track, {
direction: 'sendonly',
streams: [this._sendStream],
streams: [stream ?? this._sendStream],
sendEncodings: encodings,
});

Expand Down
1 change: 1 addition & 0 deletions src/handlers/HandlerInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export type HandlerFactory = {

export type HandlerSendOptions = {
track: MediaStreamTrack;
stream?: MediaStream;
encodings?: RtpEncodingParameters[];
codecOptions?: ProducerCodecOptions;
headerExtensionOptions?: ProducerHeaderExtensionOptions;
Expand Down
12 changes: 9 additions & 3 deletions src/handlers/ReactNative106.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class ReactNative106
// Map of RTCTransceivers indexed by MID.
private readonly _mapMidTransceiver: Map<string, RTCRtpTransceiver> =
new Map();
// Local stream for sending.
// Default local stream for sending if no stream is given.
private readonly _sendStream = new MediaStream();
// Whether a DataChannel m=application section has been created.
private _hasDataChannelMediaSection = false;
Expand Down Expand Up @@ -339,6 +339,7 @@ export class ReactNative106

async send({
track,
stream,
encodings,
codecOptions,
headerExtensionOptions,
Expand All @@ -348,7 +349,12 @@ export class ReactNative106
this.assertNotClosed();
this.assertSendDirection();

logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);
logger.debug(
'send() [kind:%s, track.id:%s, stream.id:%s]',
track.kind,
track.id,
stream?.id
);

if (encodings && encodings.length > 1) {
encodings.forEach((encoding: RtpEncodingParameters, idx: number) => {
Expand All @@ -359,7 +365,7 @@ export class ReactNative106
const mediaSectionIdx = this._remoteSdp.getNextMediaSectionIdx();
const transceiver = this._pc.addTransceiver(track, {
direction: 'sendonly',
streams: [this._sendStream],
streams: [stream ?? this._sendStream],
sendEncodings: encodings,
});

Expand Down
12 changes: 9 additions & 3 deletions src/handlers/Safari12.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class Safari12
// Map of RTCTransceivers indexed by MID.
private readonly _mapMidTransceiver: Map<string, RTCRtpTransceiver> =
new Map();
// Local stream for sending.
// Default local stream for sending if no stream is given.
private readonly _sendStream = new MediaStream();
// Whether a DataChannel m=application section has been created.
private _hasDataChannelMediaSection = false;
Expand Down Expand Up @@ -343,6 +343,7 @@ export class Safari12

async send({
track,
stream,
encodings,
codecOptions,
headerExtensionOptions,
Expand All @@ -352,12 +353,17 @@ export class Safari12
this.assertNotClosed();
this.assertSendDirection();

logger.debug('send() [kind:%s, track.id:%s]', track.kind, track.id);
logger.debug(
'send() [kind:%s, track.id:%s, stream.id:%s]',
track.kind,
track.id,
stream?.id
);

const mediaSectionIdx = this._remoteSdp.getNextMediaSectionIdx();
const transceiver = this._pc.addTransceiver(track, {
direction: 'sendonly',
streams: [this._sendStream],
streams: [stream ?? this._sendStream],
});

if (onRtpSender) {
Expand Down
21 changes: 21 additions & 0 deletions src/handlers/ortc/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,24 @@ export function addHeaderExtensionSupport(

rtpCapabilities.headerExtensions.push(newHeaderExtension);
}

export function getMsidStreamIdAndTrackId(msid?: string): {
msidStreamId?: string;
msidTrackId?: string;
} {
if (!msid || typeof msid !== 'string') {
return { msidStreamId: undefined, msidTrackId: undefined };
}

/**
* `msidStreamId` must be an id or '-' (no stream).
* `msidTrackId` is an optional id.
*/
const [msidStreamId, msidTrackId] = msid.trim().split(/\s+/);

if (!msidStreamId) {
return { msidStreamId: undefined, msidTrackId: undefined };
}

return { msidStreamId, msidTrackId };
}
3 changes: 2 additions & 1 deletion src/handlers/sdp/MediaSection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ export class OfferMediaSection extends MediaSection {
plainRtpParameters?: PlainRtpParameters;
mid: string;
kind: MediaKind | 'application';
// Those are optionals because they are only given if `kind` is a MediaKind.
offerRtpParameters?: RtpParameters;
streamId?: string;
trackId?: string;
Expand Down Expand Up @@ -518,7 +519,7 @@ export class OfferMediaSection extends MediaSection {
this._mediaObject.rtp = [];
this._mediaObject.rtcpFb = [];
this._mediaObject.fmtp = [];
this._mediaObject.msid = `${streamId ?? '-'} ${trackId}`;
this._mediaObject.msid = `${streamId} ${trackId}`;

for (const codec of offerRtpParameters!.codecs) {
const rtp: SdpTransform.MediaAttributes['rtp'][number] = {
Expand Down
Loading