Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit 747df4b

Browse files
authored
Add new properties for getting RTPTransceivers. (#491)
Background and design: docs/design/owt_with_webrtc_apis.md * Add new properties for getting senders and receivers. * Property senders is not available in P2P mode. * Add test cases. * Move transceivers to TransportSettings. * Fix a typo.
1 parent 6b5746c commit 747df4b

File tree

9 files changed

+100
-22
lines changed

9 files changed

+100
-22
lines changed

docs/design/owt_with_webrtc_apis.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ OWT(Open WebRTC Toolkit) Client SDKs provide convenient APIs to create, publish,
99
- Set preferred codecs.
1010
- Disable or enable RTX / RED / FEC.
1111
#### API Changes
12-
- A new method `getSender` will be added to `Publication`. It returns an `RTCRtpSender` for certain `Publication`.
13-
- A new method `getReceiver` will be added to `Subscription`. It returns an `RTCRtpReceiver` for certain `Subscription`.
12+
- A new member `rtpTransceivers` will be added to `TransportSettings`. It returns an array `RTCRtpReceiver`s for RTP transport.
13+
- A new member `transport` will be added to `Publication` and `Subscription`. Developers could get `RTPTransceiver`s from its `rtpTransceivers` property.
1414
- A new method `addTransceiver(DOMString trackKind, sequence<RTCRtpEncodingParameters> sendEncodings)` will be added to `ConferenceClient`. It invokes `RTCPeerConnection.addTransceiver(trackKind, {direction:inactive, sendEncodings:sendEncodings})`, returns an `RTCRtpTransceiver`. Please note that direction is `inactive` until a `publish` with return transceiver is called.
1515
- The second parameter of `ConferenceClient.publish` accepts an `RTCRtpTransceiver` created by `RTCPeerConnection.addTransceiver`. When this method is called, certain `RTCRtpTransceiver`'s direction is changed to `sendonly`, and its sender's `setStreams` is called with the first parameter's `mediaStream`.
1616
#### Server Requirements

docs/mdfiles/changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ Change Log
22
==========
33
# 5.1
44
* When subscribe a stream in conference mode, the subscribed MediaStream or BidirectionalStream is associated with a `Owt.Conference.Subscription` instead of a `Owt.Base.RemoteStream`. The `stream` property of a RemoteStream in conference mode is always undefined, while a new property `stream` is added to `Subscription`. It allows a RemoteStream to be subscribed multiple times, as well as subscribing audio and video tracks from different streams.
5+
* Add a new property `transport` to `Publication` for getting `TransportSettings`.
6+
* Add a new property `rtpTransceivers` to `TransportSettings` and `TransportConstraints`.
57
# 5.0
68
* Add WebTransport support for conference mode, see [this design doc](../../design/webtransport.md) for detailed information.
79
* All publications and subscriptions for the same conference use the same `PeerConnection`.

src/sdk/base/publication.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export class PublicationSettings {
123123
*/
124124
export class Publication extends EventDispatcher {
125125
// eslint-disable-next-line require-jsdoc
126-
constructor(id, stop, getStats, mute, unmute) {
126+
constructor(id, transport, stop, getStats, mute, unmute) {
127127
super();
128128
/**
129129
* @member {string} id
@@ -135,6 +135,18 @@ export class Publication extends EventDispatcher {
135135
writable: false,
136136
value: id ? id : Utils.createUuid(),
137137
});
138+
/**
139+
* @member {Owt.Base.TransportSettings} transport
140+
* @instance
141+
* @readonly
142+
* @desc Transport settings for the publication.
143+
* @memberof Owt.Base.Publication
144+
*/
145+
Object.defineProperty(this, 'transport', {
146+
configurable: false,
147+
writable: false,
148+
value: transport,
149+
});
138150
/**
139151
* @function stop
140152
* @instance

src/sdk/base/transport.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,29 @@ export class TransportSettings {
5656
// eslint-disable-next-line require-jsdoc
5757
constructor(type, id) {
5858
/**
59-
* @member {Array.<Owt.Base.TransportType>} type
59+
* @member {Owt.Base.TransportType} type
6060
* @instance
61-
* @memberof Owt.Base.TransportConstraints
61+
* @memberof Owt.Base.TransportSettings
6262
* @desc Transport type for publication and subscription.
6363
*/
6464
this.type = type;
6565
/**
6666
* @member {string} id
6767
* @instance
68-
* @memberof Owt.Base.TransportConstraints
68+
* @memberof Owt.Base.TransportSettings
6969
* @desc Transport ID.
7070
*/
7171
this.id = id;
72+
73+
/**
74+
* @member {?Array.<RTCRtpTransceiver>} rtpTransceivers
75+
* @instance
76+
* @memberof Owt.Base.TransportSettings
77+
* @desc A list of RTCRtpTransceiver associated with the publication or
78+
* subscription. It's only available in conference mode when TransportType
79+
* is webrtc.
80+
* @see {@link https://w3c.github.io/webrtc-pc/#rtcrtptransceiver-interface|RTCRtpTransceiver Interface of WebRTC 1.0}.
81+
*/
82+
this.rtpTransceivers = undefined;
7283
}
7384
}

src/sdk/conference/channel.js

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {Subscription} from './subscription.js';
2121
import {ConferenceError} from './error.js';
2222
import * as Utils from '../base/utils.js';
2323
import * as SdpUtils from '../base/sdputils.js';
24+
import {TransportSettings, TransportType} from '../base/transport.js';
2425

2526
/**
2627
* @class ConferencePeerConnectionChannel
@@ -876,25 +877,40 @@ export class ConferencePeerConnectionChannel extends EventDispatcher {
876877
const internalId = this._reverseIdMap.get(sessionId);
877878
if (this._subscribePromises.has(internalId)) {
878879
const mediaStream = this._remoteMediaStreams.get(sessionId);
879-
const subscription = new Subscription(sessionId, mediaStream, () => {
880-
this._unsubscribe(internalId);
881-
}, () => this._getStats(),
882-
(trackKind) => this._muteOrUnmute(sessionId, true, false, trackKind),
883-
(trackKind) => this._muteOrUnmute(sessionId, false, false, trackKind),
884-
(options) => this._applyOptions(sessionId, options));
880+
const transportSettings =
881+
new TransportSettings(TransportType.WEBRTC, this._id);
882+
transportSettings.rtpTransceivers =
883+
this._subscribeTransceivers.get(internalId).transceivers;
884+
const subscription = new Subscription(
885+
sessionId, mediaStream, transportSettings,
886+
() => {
887+
this._unsubscribe(internalId);
888+
},
889+
() => this._getStats(),
890+
(trackKind) => this._muteOrUnmute(sessionId, true, false, trackKind),
891+
(trackKind) => this._muteOrUnmute(sessionId, false, false, trackKind),
892+
(options) => this._applyOptions(sessionId, options));
885893
this._subscriptions.set(sessionId, subscription);
886894
// Resolve subscription if mediaStream is ready.
887895
if (this._subscriptions.get(sessionId).stream) {
888896
this._subscribePromises.get(internalId).resolve(subscription);
889897
this._subscribePromises.delete(internalId);
890898
}
891899
} else if (this._publishPromises.has(internalId)) {
892-
const publication = new Publication(sessionId, () => {
893-
this._unpublish(internalId);
894-
return Promise.resolve();
895-
}, () => this._getStats(),
896-
(trackKind) => this._muteOrUnmute(sessionId, true, true, trackKind),
897-
(trackKind) => this._muteOrUnmute(sessionId, false, true, trackKind));
900+
const transportSettings =
901+
new TransportSettings(TransportType.WEBRTC, this._id);
902+
transportSettings.transceivers =
903+
this._publishTransceivers.get(internalId).transceivers;
904+
const publication = new Publication(
905+
sessionId,
906+
transportSettings,
907+
() => {
908+
this._unpublish(internalId);
909+
return Promise.resolve();
910+
},
911+
() => this._getStats(),
912+
(trackKind) => this._muteOrUnmute(sessionId, true, true, trackKind),
913+
(trackKind) => this._muteOrUnmute(sessionId, false, true, trackKind));
898914
this._publications.set(sessionId, publication);
899915
this._publishPromises.get(internalId).resolve(publication);
900916
// Do not fire publication's ended event when associated stream is ended.

src/sdk/conference/subscription.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ export class SubscriptionUpdateOptions {
270270
*/
271271
export class Subscription extends EventDispatcher {
272272
// eslint-disable-next-line require-jsdoc
273-
constructor(id, stream, stop, getStats, mute, unmute, applyOptions) {
273+
constructor(
274+
id, stream, transport, stop, getStats, mute, unmute, applyOptions) {
274275
super();
275276
if (!id) {
276277
throw new TypeError('ID cannot be null or undefined.');
@@ -298,6 +299,18 @@ export class Subscription extends EventDispatcher {
298299
writable: true,
299300
value: stream,
300301
});
302+
/**
303+
* @member {Owt.Base.TransportSettings} transport
304+
* @instance
305+
* @readonly
306+
* @desc Transport settings for the subscription.
307+
* @memberof Owt.Base.Subscription
308+
*/
309+
Object.defineProperty(this, 'transport', {
310+
configurable: false,
311+
writable: false,
312+
value: transport,
313+
});
301314
/**
302315
* @function stop
303316
* @instance

src/sdk/p2p/peerconnection-channel.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,9 @@ class P2PPeerConnectionChannel extends EventDispatcher {
305305
(element) => element.mediaStream.id == mediaStreamId);
306306
const targetStream = this._publishingStreams[targetStreamIndex];
307307
this._publishingStreams.splice(targetStreamIndex, 1);
308+
// TODO: Set transceivers for Publication.
308309
const publication = new Publication(
309-
id, () => {
310+
id, undefined, () => {
310311
this._unpublish(targetStream).then(() => {
311312
publication.dispatchEvent(new OwtEvent('ended'));
312313
}, (err) => {

test/unit/resources/scripts/base.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import * as MediaStreamFactoryModule from '../../../../src/sdk/base/mediastream-
88
import * as StreamModule from '../../../../src/sdk/base/stream.js';
99
import * as MediaFormatModule from '../../../../src/sdk/base/mediaformat.js'
1010
import * as SdpUtils from '../../../../src/sdk/base/sdputils.js'
11+
import * as PublicationModule from '../../../../src/sdk/base/publication.js'
1112

1213
const expect = chai.expect;
13-
const screenSharingExtensionId = 'jniliohjdiikfjjdlpapmngebedgigjn';
1414
chai.use(chaiAsPromised);
1515
describe('Unit tests for MediaStreamFactory', function() {
1616
function createMediaStream(constraints, audioTracksExpected,
@@ -181,3 +181,15 @@ describe('Unit tests for SDP utils.', function() {
181181
done();
182182
});
183183
});
184+
185+
describe('Unit tests for Publication.', () => {
186+
it('Get senders returns all transceivers\' sender.', () => {
187+
it('Get transport returns correct TransportSettings.', () => {
188+
const transportSettings =
189+
new TransportSettings(TransportType.WEBRTC, 'randomId');
190+
const publication =
191+
new PublicationModule.Publication('sessionId', transportSettings);
192+
expect(publication.transport).to.equal(transportSettings);
193+
});
194+
});
195+
});

test/unit/resources/scripts/conference.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import {ConferenceClient} from '../../../../src/sdk/conference/client.js';
88
import {ConferencePeerConnectionChannel} from '../../../../src/sdk/conference/channel.js';
99
import * as StreamModule from '../../../../src/sdk/base/stream.js';
1010
import * as EventModule from '../../../../src/sdk/base/event.js'
11+
import * as SubscriptionModule from '../../../../src/sdk/conference/subscription.js'
12+
import { TransportSettings, TransportType } from '../../../../src/sdk/base/transport.js';
1113

1214
const expect = chai.expect;
13-
const screenSharingExtensionId = 'jniliohjdiikfjjdlpapmngebedgigjn';
1415
chai.use(chaiAsPromised);
1516

1617
describe('Unit tests for ConferenceClient', function() {
@@ -98,4 +99,14 @@ describe('Unit tests for ConferencePeerConnectionChannel.', () => {
9899
}
99100
});
100101
});
102+
});
103+
104+
describe('Unit tests for Subscription.', () => {
105+
it('Get transport returns correct TransportSettings.', () => {
106+
const transportSettings =
107+
new TransportSettings(TransportType.WEBRTC, 'randomId');
108+
const subscription = new SubscriptionModule.Subscription(
109+
'sessionId', undefined, transportSettings);
110+
expect(subscription.transport).to.equal(transportSettings);
111+
});
101112
});

0 commit comments

Comments
 (0)