跳转到主要内容
DeviceManager.shared 是单例,管输入设备的枚举与选择。 音频输出路由(扬声器 / 听筒 / 蓝牙)是另一套,见音频路由。

枚举设备

DeviceInfo 的字段:deviceId、name、kind、isDefault。
UI 上做设备下拉框时用 cachedDevices() 更合适 —— 它不会每次渲染都去查系统。 配合下面的热插拔事件刷新缓存即可。

切换摄像头

枚举出来的 deviceId 可以直接喂回采集参数,这条回路是设备切换能力的地基:
采集失败时,若该类设备一个都没有、或指定的 deviceId 已不在枚举结果里(例如外设已拔出),1.1.0 起抛 deviceNotFound(108021),其它原因抛 captureError(108018),见错误码。

切换麦克风

有两条路:
changeDeviceId() 会换一条底层轨道,已发布的轨道必须重新发布, 否则对端收到的还是旧设备的音频。详见静音与停止发布。

输出设备

setOutputDevice(deviceId) 在鸿蒙上恒抛错。 系统不支持指定任意音频输出设备(CommunicationDeviceType 只有 SPEAKER),调用即抛 featureNotSupported(108032;1.0.1 及以前为 invalidState 108024)。切外放请用 setSpeakerOutputPreferred(),外接设备请引导用户到系统音频面板选择。
setSpeakerOutputPreferred(true/false) 与 AudioRouteSession 的 defaultAudioRoute 管的是同一件事的不同层次。做通话类 UI 建议统一用 AudioRouteSession —— 它区分”持久设置”与”通话中临时切换”,语义更清晰。

热插拔

isMonitoring 可以回读监听状态。
delegates 是强引用,必须成对 add / remove。DeviceManager.shared 是全局单例,注册在它上面的 delegate 不摘除就是永久泄漏 —— 页面早就销毁了,回调还在往一个不该存在的对象上打。
比较两次枚举结果的差异可以用现成的工具函数:

实测的设备形态

在一台 HUAWEI nova 12 Pro(HarmonyOS 6.1)上:
默认摄像头是后置。 做视频通话通常要显式指定前置 —— 用 CameraPosition.front(defaultCameraCaptureOptions() 已经是前置), 或按 deviceId 指定。

相关阅读