Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion packages/@webex/media-helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"deploy:npm": "yarn npm publish"
},
"dependencies": {
"@webex/internal-media-core": "2.26.1",
"@webex/internal-media-core": "2.26.2",
"@webex/ts-events": "^1.1.0",
"@webex/web-media-effects": "2.33.5"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/@webex/plugin-meetings/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
},
"dependencies": {
"@webex/common": "workspace:*",
"@webex/internal-media-core": "2.26.1",
"@webex/internal-media-core": "2.26.2",
"@webex/internal-plugin-conversation": "workspace:*",
"@webex/internal-plugin-device": "workspace:*",
"@webex/internal-plugin-llm": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,63 @@ WebExMeetingsErrors[IceGatheringFailed.CODE] = IceGatheringFailed;
class AddMediaFailed extends WebexMeetingsError {
static CODE = 30203;
cause?: Error;
connectionType?: string;
Comment thread
marcin-bazyl marked this conversation as resolved.
selectedCandidatePairChanges?: number;
numTransports?: number;
iceConnected?: boolean;

/**
* Creates a new AddMediaFailed error
* @param {Error} [cause] - The underlying error that caused the media addition to fail
* @param {Object} options
* @param {Error} [options.cause] - The underlying error that caused the media addition to fail
* @param {string} [options.connectionType] - The ICE connection type at the time of failure (e.g. 'UDP', 'TURN-TLS')
* @param {number} [options.selectedCandidatePairChanges] - Number of times the selected candidate pair changed
* @param {number} [options.numTransports] - Number of ICE transports
* @param {boolean} [options.iceConnected] - Whether ICE connection was established before the failure
*/
constructor(cause?: Error) {
constructor(
options: {
cause?: Error;
connectionType?: string;
selectedCandidatePairChanges?: number;
numTransports?: number;
iceConnected?: boolean;
} = {}
) {
super(AddMediaFailed.CODE, 'Failed to add media');
this.cause = cause;
this.cause = options.cause;
this.connectionType = options.connectionType;
this.selectedCandidatePairChanges = options.selectedCandidatePairChanges;
this.numTransports = options.numTransports;
this.iceConnected = options.iceConnected;
}

/**
* Returns true if the failure was due to a DTLS handshake failure
* (ICE connected successfully but the overall media connection failed).
*/
get isDtlsHandshakeFailure(): boolean {
return this.iceConnected === true;
}
}
export {AddMediaFailed};
WebExMeetingsErrors[AddMediaFailed.CODE] = AddMediaFailed;

/**
* @class MediaConnectionTimedOutError
* @classdesc Internal error thrown when the media connection times out waiting to connect.
*/
class MediaConnectionTimedOutError extends Error {
iceConnected: boolean;

constructor(message: string, iceConnected: boolean) {
super(message);
this.name = 'MediaConnectionTimedOutError';
this.iceConnected = iceConnected;
}
}
export {MediaConnectionTimedOutError};

/**
* @class SdpResponseTimeoutError
* @classdesc Raised whenever we timeout waiting for remote SDP answer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export interface MediaConnectionAwaiterProps {
correlationId: string;
}

export interface FailureResult {
iceConnected: boolean;
}

/**
* @class MediaConnectionAwaiter
*/
Expand Down Expand Up @@ -58,6 +62,17 @@ export default class MediaConnectionAwaiter {
return this.webrtcMediaConnection.getConnectionState() === ConnectionState.Failed;
}

/**
* Returns true if ICE connection state indicates connectivity.
*
* @returns {boolean}
*/
private isIceConnected(): boolean {
const state = this.webrtcMediaConnection.getIceConnectionState();

return state === 'connected' || state === 'completed';
}

/**
* Returns true if the ICE Gathering is completed, false otherwise.
*
Expand Down Expand Up @@ -105,7 +120,7 @@ export default class MediaConnectionAwaiter {

this.defer.reject({
iceConnected: this.iceConnected,
});
} satisfies FailureResult);
}

if (!this.isConnected()) {
Expand Down Expand Up @@ -148,7 +163,7 @@ export default class MediaConnectionAwaiter {
`Media:MediaConnectionAwaiter#iceConnectionStateHandler --> ICE connection state change -> ${iceConnectionState}`
);

if (iceConnectionState === 'connected' && !this.iceConnected) {
if (this.isIceConnected() && !this.iceConnected) {
this.iceConnected = true;
}

Expand Down Expand Up @@ -249,13 +264,13 @@ export default class MediaConnectionAwaiter {

this.defer.reject({
iceConnected: this.iceConnected,
});
} satisfies FailureResult);
Comment thread
marcin-bazyl marked this conversation as resolved.
}

/**
* Waits for the webrtc media connection to be connected.
*
* @returns {Promise}
* @returns {Promise<void>} In case of failure, the promise is rejected with FailureResult
Comment thread
marcin-bazyl marked this conversation as resolved.
*/
waitForMediaConnectionConnected(): Promise<void> {
if (this.isConnected()) {
Expand All @@ -269,6 +284,8 @@ export default class MediaConnectionAwaiter {
'Media:MediaConnectionAwaiter#waitForMediaConnectionConnected --> Waiting for media connection to be connected'
);

this.iceConnected = this.isIceConnected();

this.webrtcMediaConnection.on(
MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED,
this.peerConnectionStateCallback
Expand Down
8 changes: 7 additions & 1 deletion packages/@webex/plugin-meetings/src/media/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Media.createMediaConnection = (
enableExtmap?: boolean;
turnServerInfo?: TurnServerInfo;
bundlePolicy?: BundlePolicy;
iceTransportPolicy?: RTCIceTransportPolicy;
iceCandidatesTimeout?: number;
disableAudioMainDtx?: boolean;
enableAudioTwcc?: boolean;
Expand All @@ -157,6 +158,7 @@ Media.createMediaConnection = (
enableExtmap,
turnServerInfo,
bundlePolicy,
iceTransportPolicy,
iceCandidatesTimeout,
disableAudioMainDtx,
enableAudioTwcc,
Expand All @@ -167,7 +169,7 @@ Media.createMediaConnection = (
const iceServers = [];

// we might not have any TURN server if TURN discovery failed or wasn't done or we land on a video mesh node
if (turnServerInfo?.urls.length > 0) {
if (turnServerInfo && turnServerInfo.urls.length > 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: why not turnServerInfo?.urls?.length > 0 ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I remove turnServerInfo check here, then we have to add ?. to lines 175-177 too, so I prefer it this way

// TURN-TLS server
iceServers.push({
urls: turnServerInfo.urls,
Expand All @@ -187,6 +189,10 @@ Media.createMediaConnection = (
config.bundlePolicy = bundlePolicy;
}

if (iceTransportPolicy) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: I'd love a comment on here for iceTransportPolicy, i.e., what it is, since this is a top level and we're adding a new config value.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the type is clear that it's a browser level thing - RTCIceTransportPolicy, so then the natural thing to do is to google it and see the MDN page which will have a lot more and up-to-date info than what I can fit in a comment

config.iceTransportPolicy = iceTransportPolicy;
Comment thread
marcin-bazyl marked this conversation as resolved.
}

if (disableAudioMainDtx !== undefined) {
config.disableAudioMainDtx = disableAudioMainDtx;
}
Expand Down
Loading
Loading