Set available devices to empty map on safari.

Signed-off-by: Timo K <toger5@hotmail.de>
This commit is contained in:
Timo K
2025-07-29 17:10:40 +02:00
parent e14ad21c4e
commit 04bc4175f4
3 changed files with 8 additions and 4 deletions

View File

@@ -182,7 +182,7 @@ interface StereoPanAudioTrackProps {
/** /**
* This wraps `livekit.AudioTrack` to allow adding audio nodes to a track. * This wraps `livekit.AudioTrack` to allow adding audio nodes to a track.
* It main purpose is to remount the AudioTrack component when switching from * It main purpose is to remount the AudioTrack component when switching from
* audiooContext to normal audio playback. * audioContext to normal audio playback.
* As of now the AudioTrack component does not support adding audio nodes while being mounted. * As of now the AudioTrack component does not support adding audio nodes while being mounted.
* @param param0 * @param param0
* @returns * @returns
@@ -202,7 +202,7 @@ function AudioTrackWithAudioNodes({
const [trackReady, setTrackReady] = useReactiveState( const [trackReady, setTrackReady] = useReactiveState(
() => false, () => false,
// We only want the track to reset once both (audioNodes and audioContext) are set. // We only want the track to reset once both (audioNodes and audioContext) are set.
// for unsetting the audioContext its enough if one of the the is undefined. // for unsetting the audioContext its enough if one of the two is undefined.
[audioContext && audioNodes], [audioContext && audioNodes],
); );

View File

@@ -150,7 +150,7 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
?.disconnect() ?.disconnect()
.then(() => { .then(() => {
logger.info( logger.info(
`[Lifecycle] Disconnected from livekite room, state:${livekitRoom?.state}`, `[Lifecycle] Disconnected from livekit room, state:${livekitRoom?.state}`,
); );
}) })
.catch((e) => { .catch((e) => {

View File

@@ -211,7 +211,7 @@ class AudioOutput
public readonly available$ = this.scope.behavior( public readonly available$ = this.scope.behavior(
availableRawDevices$("audiooutput", this.usingNames$, this.scope).pipe( availableRawDevices$("audiooutput", this.usingNames$, this.scope).pipe(
map((availableRaw) => { map((availableRaw) => {
const available: Map<string, AudioOutputDeviceLabel> = let available: Map<string, AudioOutputDeviceLabel> =
buildDeviceMap(availableRaw); buildDeviceMap(availableRaw);
// Create a virtual default audio output for browsers that don't have one. // Create a virtual default audio output for browsers that don't have one.
// Its device ID must be the empty string because that's what setSinkId // Its device ID must be the empty string because that's what setSinkId
@@ -221,6 +221,10 @@ class AudioOutput
type: "default", type: "default",
name: availableRaw[0]?.label || null, name: availableRaw[0]?.label || null,
}); });
if (navigator.userAgent.includes("Safari")) {
// set to empty map if we are on Safari, because it does not support setSinkId
available = new Map();
}
// Note: creating virtual default input devices would be another problem // Note: creating virtual default input devices would be another problem
// entirely, because requesting a media stream from deviceId "" won't // entirely, because requesting a media stream from deviceId "" won't
// automatically track the default device. // automatically track the default device.