Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions .changeset/tricky-comics-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/media-signaling': patch
---

Fixes an issue where voice calls could fail if the user navigated between rooms during the initial connection
3 changes: 2 additions & 1 deletion packages/media-signaling/src/lib/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
import type { IClientMediaCall, CallActorType, CallContact, CallFeature, AnyMediaCallData } from '../definition/call';
import type { IMediaSignalLogger } from '../definition/logger';
import { SessionRegistration } from './components/SessionRegistration';
import { isSameDeviceId } from './utils/isSameDeviceId';

export type MediaSignalingEvents = {
sessionStateChange: void;
Expand Down Expand Up @@ -249,7 +250,7 @@ export class MediaSignalingSession extends Emitter<MediaSignalingEvents> {
// 1. doesn't have any input track yet
// 2. it's the same device id
// 3. has no restriction on which device to use
if (!this.inputTrack || deviceId === this.currentDeviceId || !deviceId) {
if (!this.inputTrack || !deviceId || isSameDeviceId(deviceId, this.currentDeviceId)) {
return;
}

Expand Down
71 changes: 71 additions & 0 deletions packages/media-signaling/src/lib/utils/isSameDeviceId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
function ensureStringArray(value: string | string[] | undefined): string[] {
if (!value) {
return [];
}

if (typeof value === 'string') {
return [value];
}

if (Array.isArray(value)) {
return value;
}

return [];
}

function normalizeDeviceId(deviceId: ConstrainDOMString | null): { exact: string[]; ideal: string[] } {
if (!deviceId) {
return {
exact: [],
ideal: [],
};
}

if (typeof deviceId === 'object' && !Array.isArray(deviceId)) {
return {
exact: ensureStringArray(deviceId.exact),
ideal: ensureStringArray(deviceId.ideal),
};
}

return {
exact: ensureStringArray(deviceId),
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Resolved
ideal: [],
};
}

function isSameStringArray(array1: string[], array2: string[]): boolean {
const uniqueArray1 = [...new Set(array1)];
const uniqueArray2 = [...new Set(array2)];

if (uniqueArray1.length !== uniqueArray2.length) {
return false;
}

for (const value of uniqueArray1) {
if (!uniqueArray2.includes(value)) {
return false;
}
}

return true;
}

export function isSameDeviceId(deviceId1: ConstrainDOMString | null, deviceId2: ConstrainDOMString | null): boolean {
if (deviceId1 === deviceId2 || (!deviceId1 && !deviceId2)) {
return true;
}

const normalizedDeviceId1 = normalizeDeviceId(deviceId1);
const normalizedDeviceId2 = normalizeDeviceId(deviceId2);

if (!isSameStringArray(normalizedDeviceId1.exact, normalizedDeviceId2.exact)) {
return false;
}
if (!isSameStringArray(normalizedDeviceId1.ideal, normalizedDeviceId2.ideal)) {
return false;
}

return true;
}
Loading