Ignore spurious 'devicechange' events

This gives us the additional insurance of breaking the Safari media acquisition loop at the source by admitting that they can be spurious in practice. Safari, why!?
This commit is contained in:
Robin
2025-06-04 11:23:20 -04:00
parent 83bfb721e7
commit 40b351d76d

View File

@@ -17,9 +17,10 @@ import {
type JSX,
} from "react";
import { createMediaDeviceObserver } from "@livekit/components-core";
import { combineLatest, map, startWith } from "rxjs";
import { combineLatest, distinctUntilChanged, map, startWith } from "rxjs";
import { useObservable, useObservableEagerState } from "observable-hooks";
import { logger } from "matrix-js-sdk/lib/logger";
import { isEqual } from "lodash-es";
import {
useSetting,
@@ -140,7 +141,13 @@ function useMediaDeviceHandle(
kind,
() => logger.error("Error creating MediaDeviceObserver"),
requestPermissions,
).pipe(startWith([])),
// This Observable emits new values whenever the browser fires a
// MediaDevices 'devicechange' event. One would think, innocently, that
// a 'devicechange' event means the devices have changed. But as of the
// time of writing, we are seeing mobile Safari firing spurious
// 'devicechange' events (where no change has actually occurred) when
// we call MediaDevices.getUserMedia. So, filter by deep equality.
).pipe(startWith([]), distinctUntilChanged<MediaDeviceInfo[]>(isEqual)),
[kind, requestPermissions],
);
const available = useObservableEagerState(