Skip to content
Open
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
11 changes: 7 additions & 4 deletions src/room/Room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
const abortController = new AbortController();

// in order to catch device changes prior to room connection we need to register the event in the constructor
navigator.mediaDevices?.addEventListener('devicechange', this.handleDeviceChange, {
navigator.mediaDevices?.addEventListener?.('devicechange', this.handleDeviceChange, {
signal: abortController.signal,
});

Expand Down Expand Up @@ -1615,7 +1615,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
window.removeEventListener('beforeunload', this.onPageLeave);
window.removeEventListener('pagehide', this.onPageLeave);
window.removeEventListener('freeze', this.onPageLeave);
navigator.mediaDevices?.removeEventListener('devicechange', this.handleDeviceChange);
navigator.mediaDevices?.removeEventListener?.('devicechange', this.handleDeviceChange);
}
} finally {
this.setAndEmitConnectionState(ConnectionState.Disconnected);
Expand Down Expand Up @@ -2500,7 +2500,8 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
new LocalVideoTrack(
publishOptions.useRealTracks
? (
await window.navigator.mediaDevices.getUserMedia({ video: true })
(await window.navigator.mediaDevices?.getUserMedia?.({ video: true })) ??
new MediaStream()
).getVideoTracks()[0]
Copy link
Author

Choose a reason for hiding this comment

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

Note: The getUserMedia calls with ?? new MediaStream() fallback (lines 2502, 2529)
ensure we don't get undefined when calling .getVideoTracks()[0] in non-secure contexts
where mediaDevices?.getUserMedia?.() returns undefined due to optional chaining.

Copy link
Contributor

@lukasIO lukasIO Nov 28, 2025

Choose a reason for hiding this comment

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

instead of falling back to new MediaStream() we could simply check for publishOptions.useRealTracks && window.navigator.mediaDevices?.getUserMedia above

: createDummyVideoStreamTrack(
160 * (participantOptions.aspectRatios[0] ?? 1),
Expand Down Expand Up @@ -2528,7 +2529,9 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
}),
new LocalAudioTrack(
publishOptions.useRealTracks
? (await navigator.mediaDevices.getUserMedia({ audio: true })).getAudioTracks()[0]
? (
(await navigator.mediaDevices?.getUserMedia?.({ audio: true })) ?? new MediaStream()
).getAudioTracks()[0]
: getEmptyAudioStreamTrack(),
undefined,
false,
Expand Down
Loading