Skip to content

Commit 829c3e0

Browse files
authored
Add header extension options to transport.produce() (#350)
1 parent cfa2bf9 commit 829c3e0

File tree

9 files changed

+306
-15
lines changed

9 files changed

+306
-15
lines changed

src/Producer.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type ProducerOptions<ProducerAppData extends AppData = AppData> = {
1515
track?: MediaStreamTrack;
1616
encodings?: RtpEncodingParameters[];
1717
codecOptions?: ProducerCodecOptions;
18+
headerExtensionOptions?: ProducerHeaderExtensionOptions;
1819
codec?: RtpCodecCapability;
1920
stopTracks?: boolean;
2021
disableTrackOnPause?: boolean;
@@ -43,6 +44,11 @@ export type ProducerCodecOptions = {
4344
videoGoogleMinBitrate?: number;
4445
};
4546

47+
// https://mediasoup.org/documentation/v3/mediasoup-client/api/#HeaderExtensionOptions
48+
export type ProducerHeaderExtensionOptions = {
49+
absCaptureTime?: boolean;
50+
};
51+
4652
export type ProducerEvents = {
4753
transportclose: [];
4854
trackended: [];

src/Transport.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ export class Transport<
502502
track,
503503
encodings,
504504
codecOptions,
505+
headerExtensionOptions,
505506
codec,
506507
stopTracks = true,
507508
disableTrackOnPause = true,
@@ -588,6 +589,7 @@ export class Transport<
588589
track,
589590
encodings: normalizedEncodings,
590591
codecOptions,
592+
headerExtensionOptions,
591593
codec,
592594
onRtpSender,
593595
});

src/handlers/Chrome111.ts

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import type {
1010
RtpCapabilities,
1111
MediaKind,
1212
ExtendedRtpCapabilities,
13+
RtpHeaderExtensionUri,
14+
RtpHeaderExtensionDirection,
1315
} from '../RtpParameters';
1416
import type { SctpCapabilities, SctpStreamParameters } from '../SctpParameters';
1517
import * as sdpCommonUtils from './sdp/commonUtils';
@@ -126,7 +128,12 @@ export class Chrome111
126128
}
127129

128130
private static getLocalRtpCapabilities(
129-
localSdpObject: SdpTransform.SessionDescription
131+
localSdpObject: SdpTransform.SessionDescription,
132+
extraHeaderExtensions: {
133+
uri: RtpHeaderExtensionUri;
134+
kind: MediaKind;
135+
direction: RtpHeaderExtensionDirection;
136+
}[] = []
130137
): RtpCapabilities {
131138
const nativeRtpCapabilities = sdpCommonUtils.extractRtpCapabilities({
132139
sdpObject: localSdpObject,
@@ -138,6 +145,13 @@ export class Chrome111
138145
// libwebrtc supports NACK for OPUS but doesn't announce it.
139146
ortcUtils.addNackSupportForOpus(nativeRtpCapabilities);
140147

148+
for (const headerExtension of extraHeaderExtensions) {
149+
ortcUtils.addHeaderExtensionSupport(
150+
nativeRtpCapabilities,
151+
headerExtension
152+
);
153+
}
154+
141155
return nativeRtpCapabilities;
142156
}
143157

@@ -324,6 +338,7 @@ export class Chrome111
324338
track,
325339
encodings,
326340
codecOptions,
341+
headerExtensionOptions,
327342
codec,
328343
onRtpSender,
329344
}: HandlerSendOptions): Promise<HandlerSendResult> {
@@ -367,15 +382,30 @@ export class Chrome111
367382
onRtpSender(transceiver.sender);
368383
}
369384

370-
const offer = await this._pc.createOffer();
385+
let offer = await this._pc.createOffer();
371386
let localSdpObject = sdpTransform.parse(offer.sdp!);
372387

373388
if (localSdpObject.extmapAllowMixed) {
374389
this._remoteSdp.setSessionExtmapAllowMixed();
375390
}
376391

377-
const nativeRtpCapabilities =
378-
Chrome111.getLocalRtpCapabilities(localSdpObject);
392+
const extraHeaderExtensions: {
393+
uri: RtpHeaderExtensionUri;
394+
kind: MediaKind;
395+
direction: RtpHeaderExtensionDirection;
396+
}[] = [];
397+
398+
extraHeaderExtensions.push({
399+
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time',
400+
kind: track.kind as MediaKind,
401+
direction: 'sendonly',
402+
});
403+
404+
const nativeRtpCapabilities = Chrome111.getLocalRtpCapabilities(
405+
localSdpObject,
406+
extraHeaderExtensions
407+
);
408+
379409
const sendExtendedRtpCapabilities = this._getSendExtendedRtpCapabilities(
380410
nativeRtpCapabilities
381411
);
@@ -411,6 +441,27 @@ export class Chrome111
411441
});
412442
}
413443

444+
// Optimize. Only generate new offer if needed.
445+
if (headerExtensionOptions?.absCaptureTime) {
446+
const offerMediaObject = localSdpObject.media[mediaSectionIdx.idx]!;
447+
448+
sdpCommonUtils.addHeaderExtension({
449+
offerMediaObject,
450+
headerExtensionUri:
451+
'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time',
452+
headerExtensionId: sendingRemoteRtpParameters.headerExtensions!.find(
453+
headerExtension =>
454+
headerExtension.uri ===
455+
'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time'
456+
)!.id,
457+
});
458+
459+
offer = {
460+
type: 'offer',
461+
sdp: sdpTransform.write(localSdpObject),
462+
};
463+
}
464+
414465
logger.debug('send() | calling pc.setLocalDescription() [offer:%o]', offer);
415466

416467
await this._pc.setLocalDescription(offer);

src/handlers/Chrome74.ts

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import type {
1111
MediaKind,
1212
RtpEncodingParameters,
1313
ExtendedRtpCapabilities,
14+
RtpHeaderExtensionUri,
15+
RtpHeaderExtensionDirection,
1416
} from '../RtpParameters';
1517
import type { SctpCapabilities, SctpStreamParameters } from '../SctpParameters';
1618
import * as sdpCommonUtils from './sdp/commonUtils';
@@ -123,7 +125,12 @@ export class Chrome74
123125
}
124126

125127
private static getLocalRtpCapabilities(
126-
localSdpObject: SdpTransform.SessionDescription
128+
localSdpObject: SdpTransform.SessionDescription,
129+
extraHeaderExtensions: {
130+
uri: RtpHeaderExtensionUri;
131+
kind: MediaKind;
132+
direction: RtpHeaderExtensionDirection;
133+
}[] = []
127134
): RtpCapabilities {
128135
const nativeRtpCapabilities = sdpCommonUtils.extractRtpCapabilities({
129136
sdpObject: localSdpObject,
@@ -135,6 +142,13 @@ export class Chrome74
135142
// libwebrtc supports NACK for OPUS but doesn't announce it.
136143
ortcUtils.addNackSupportForOpus(nativeRtpCapabilities);
137144

145+
for (const headerExtension of extraHeaderExtensions) {
146+
ortcUtils.addHeaderExtensionSupport(
147+
nativeRtpCapabilities,
148+
headerExtension
149+
);
150+
}
151+
138152
return nativeRtpCapabilities;
139153
}
140154

@@ -321,6 +335,7 @@ export class Chrome74
321335
track,
322336
encodings,
323337
codecOptions,
338+
headerExtensionOptions,
324339
codec,
325340
}: HandlerSendOptions): Promise<HandlerSendResult> {
326341
this.assertNotClosed();
@@ -347,8 +362,23 @@ export class Chrome74
347362
this._remoteSdp.setSessionExtmapAllowMixed();
348363
}
349364

350-
const nativeRtpCapabilities =
351-
Chrome74.getLocalRtpCapabilities(localSdpObject);
365+
const extraHeaderExtensions: {
366+
uri: RtpHeaderExtensionUri;
367+
kind: MediaKind;
368+
direction: RtpHeaderExtensionDirection;
369+
}[] = [];
370+
371+
extraHeaderExtensions.push({
372+
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time',
373+
kind: track.kind as MediaKind,
374+
direction: 'sendonly',
375+
});
376+
377+
const nativeRtpCapabilities = Chrome74.getLocalRtpCapabilities(
378+
localSdpObject,
379+
extraHeaderExtensions
380+
);
381+
352382
const sendExtendedRtpCapabilities = this._getSendExtendedRtpCapabilities(
353383
nativeRtpCapabilities
354384
);
@@ -418,6 +448,27 @@ export class Chrome74
418448

419449
logger.debug('send() | calling pc.setLocalDescription() [offer:%o]', offer);
420450

451+
// Optimize. Only generate new offer if needed.
452+
if (headerExtensionOptions?.absCaptureTime) {
453+
offerMediaObject = localSdpObject.media[mediaSectionIdx.idx]!;
454+
455+
sdpCommonUtils.addHeaderExtension({
456+
offerMediaObject,
457+
headerExtensionUri:
458+
'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time',
459+
headerExtensionId: sendingRemoteRtpParameters.headerExtensions!.find(
460+
headerExtension =>
461+
headerExtension.uri ===
462+
'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time'
463+
)!.id,
464+
});
465+
466+
offer = {
467+
type: 'offer',
468+
sdp: sdpTransform.write(localSdpObject),
469+
};
470+
}
471+
421472
await this._pc.setLocalDescription(offer);
422473

423474
// We can now get the transceiver.mid.

src/handlers/HandlerInterface.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import type {
66
IceGatheringState,
77
ConnectionState,
88
} from '../Transport';
9-
import type { ProducerCodecOptions, OnRtpSenderCallback } from '../Producer';
9+
import type {
10+
ProducerCodecOptions,
11+
ProducerHeaderExtensionOptions,
12+
OnRtpSenderCallback,
13+
} from '../Producer';
1014
import type { OnRtpReceiverCallback } from '../Consumer';
1115
import type {
1216
RtpCapabilities,
@@ -46,6 +50,7 @@ export type HandlerSendOptions = {
4650
track: MediaStreamTrack;
4751
encodings?: RtpEncodingParameters[];
4852
codecOptions?: ProducerCodecOptions;
53+
headerExtensionOptions?: ProducerHeaderExtensionOptions;
4954
codec?: RtpCodecCapability;
5055
onRtpSender?: OnRtpSenderCallback;
5156
};

src/handlers/ReactNative106.ts

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import type {
1111
MediaKind,
1212
RtpEncodingParameters,
1313
ExtendedRtpCapabilities,
14+
RtpHeaderExtensionUri,
15+
RtpHeaderExtensionDirection,
1416
} from '../RtpParameters';
1517
import type { SctpCapabilities, SctpStreamParameters } from '../SctpParameters';
1618
import type {
@@ -124,7 +126,12 @@ export class ReactNative106
124126
}
125127

126128
private static getLocalRtpCapabilities(
127-
localSdpObject: SdpTransform.SessionDescription
129+
localSdpObject: SdpTransform.SessionDescription,
130+
extraHeaderExtensions: {
131+
uri: RtpHeaderExtensionUri;
132+
kind: MediaKind;
133+
direction: RtpHeaderExtensionDirection;
134+
}[] = []
128135
): RtpCapabilities {
129136
const nativeRtpCapabilities = sdpCommonUtils.extractRtpCapabilities({
130137
sdpObject: localSdpObject,
@@ -136,6 +143,13 @@ export class ReactNative106
136143
// libwebrtc supports NACK for OPUS but doesn't announce it.
137144
ortcUtils.addNackSupportForOpus(nativeRtpCapabilities);
138145

146+
for (const headerExtension of extraHeaderExtensions) {
147+
ortcUtils.addHeaderExtensionSupport(
148+
nativeRtpCapabilities,
149+
headerExtension
150+
);
151+
}
152+
139153
return nativeRtpCapabilities;
140154
}
141155

@@ -327,6 +341,7 @@ export class ReactNative106
327341
track,
328342
encodings,
329343
codecOptions,
344+
headerExtensionOptions,
330345
codec,
331346
onRtpSender,
332347
}: HandlerSendOptions): Promise<HandlerSendResult> {
@@ -359,8 +374,23 @@ export class ReactNative106
359374
this._remoteSdp.setSessionExtmapAllowMixed();
360375
}
361376

362-
const nativeRtpCapabilities =
363-
ReactNative106.getLocalRtpCapabilities(localSdpObject);
377+
const extraHeaderExtensions: {
378+
uri: RtpHeaderExtensionUri;
379+
kind: MediaKind;
380+
direction: RtpHeaderExtensionDirection;
381+
}[] = [];
382+
383+
extraHeaderExtensions.push({
384+
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time',
385+
kind: track.kind as MediaKind,
386+
direction: 'sendonly',
387+
});
388+
389+
const nativeRtpCapabilities = ReactNative106.getLocalRtpCapabilities(
390+
localSdpObject,
391+
extraHeaderExtensions
392+
);
393+
364394
const sendExtendedRtpCapabilities = this._getSendExtendedRtpCapabilities(
365395
nativeRtpCapabilities
366396
);
@@ -428,6 +458,27 @@ export class ReactNative106
428458
};
429459
}
430460

461+
// Optimize. Only generate new offer if needed.
462+
if (headerExtensionOptions?.absCaptureTime) {
463+
offerMediaObject = localSdpObject.media[mediaSectionIdx.idx]!;
464+
465+
sdpCommonUtils.addHeaderExtension({
466+
offerMediaObject,
467+
headerExtensionUri:
468+
'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time',
469+
headerExtensionId: sendingRemoteRtpParameters.headerExtensions!.find(
470+
headerExtension =>
471+
headerExtension.uri ===
472+
'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time'
473+
)!.id,
474+
});
475+
476+
offer = {
477+
type: 'offer',
478+
sdp: sdpTransform.write(localSdpObject),
479+
};
480+
}
481+
431482
logger.debug('send() | calling pc.setLocalDescription() [offer:%o]', offer);
432483

433484
await this._pc.setLocalDescription(offer);

0 commit comments

Comments
 (0)