livekit / client-sdk-flutter

Flutter Client SDK for LiveKit
https://docs.livekit.io
Apache License 2.0
229 stars 108 forks source link

Messy audio device ids #511

Closed cgarbacea closed 1 month ago

cgarbacea commented 1 month ago

Can we please do something about the audio ids or add a simple type like builtin | bluetooth | wired, both Android and iOS provie this identification in native (not sure about "wired" :) )

To me it looks like this on Android with some Bluetooth headset attached:

Screenshot 2024-05-07 at 19 32 06

On iOS until I set select the AirPods it looks like this:

Screenshot 2024-05-07 at 19 33 25

After I set the AirPods as the input device it looks like this:

Screenshot 2024-05-07 at 19 35 02

The bigger issue is the deviceId: I can't relay on the deviceId or anything to sync the Input/Output, when I switch from one input to another (e.g. select Airpods as the input an i am still on Speaker for the Output) I need to be able to switch to the bluetooth device when I detect a change with onDeviceChange.stream.listener, but due to the inconsitency in naming - I don't see away to do it

Please let me know if I am missing sommething.

livekit_client: ^2.1.3

davidliu commented 1 month ago

@cloudwebrtc I think may want to expose groupId in MediaDevice. The iOS exposes the portType, which I think should be enough to handle this.

davidliu commented 1 month ago

@cgarbacea as an intermediate solution to unblock, you can cross reference against the underlying enumerateDevices() function:

import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;

var mediaDeviceInfos = await rtc.navigator.mediaDevices.enumerateDevices();

Each MediaDeviceInfo object should have a groupId field; on iOS, this corresponds to the AVAudioSession.Port of the output.

cgarbacea commented 1 month ago

thanks for the tip, I'll try your suggestion.

cgarbacea commented 1 month ago

It won't make a difference the response from rtc is identical. True, there is a groupId but it is inconsistent, "null" where it will matter :) I belive you just found the root cause - the issue is in "rtc" we'll need a better mapping from native e.g.: /// Type of MediaDevice (ex: Bluetooth Audio, Front Camera) public let type: MediaDeviceType

`@objc public enum MediaDeviceType: Int, CustomStringConvertible {
case audioBluetooth
case audioWiredHeadset
case audioBuiltInSpeaker
case audioHandset
case videoFrontCamera
case videoBackCamera
case other

public var description: String {
    switch self {
    case .audioBluetooth:
        return "audioBluetooth"
    case .audioWiredHeadset:
        return "audioWiredHeadset"
    case .audioBuiltInSpeaker:
        return "audioBuiltInSpeaker"
    case .audioHandset:
        return "audioHandset"
    case .videoFrontCamera:
        return "videoFrontCamera"
    case .videoBackCamera:
        return "videoBackCamera"
    case .other:
        return "other"
    }
}

}`

and something similar for Android, maybe pulled from android.media.AudioDeviceInfo and android.hardware.camera2.CameraMetadata

davidliu commented 1 month ago

Is this a separate issue? The audio input/output devices should properly set groupId.

Tested it and all the audio related devices gave their port type.

cgarbacea commented 1 month ago

to me it looks like this in Android:

Screenshot 2024-05-09 at 13 18 17

iOS:

Screenshot 2024-05-09 at 13 24 21

Android mostly "null" or number as string that I cannot relay on iOS, I can trust bluetooth will always be called "BluetoothHFP"

cloudwebrtc commented 1 month ago

@cgarbacea This PR should be a valid fix. https://github.com/flutter-webrtc/flutter-webrtc/pull/1583

Fixed output to ensure each groupId, and deviceId are valid and avoid using numbers to identify audio devices

cgarbacea commented 1 month ago

yeah, very nice - thanks

furkanKotic commented 1 month ago

@cloudwebrtc The problem in the link may be the bug on the IOS side. Could you please review the issue?

https://github.com/livekit/client-sdk-flutter/issues/376