# 音视频设备管理 (/zh-CN/realtime-media/rtc/build/initialize-and-channel/switch-device)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

声网 Web SDK 提供 API 用于音视频设备管理，例如在通话过程中动态切换音视频采集设备、处理音视频采集设备热插拔逻辑等。

## 前提条件 [#前提条件]

开始前，请确保你已参考[快速开始](/zh-CN/realtime-media/rtc/get-started/quick-start)在你的项目中实现基本的实时音视频功能。

## 实现方法 [#实现方法]
### 切换音视频设备 [#切换音视频设备]

在创建本地音视频轨道时，可以通过指定 `cameraId` 和 `microphoneId` 来指定音视频设备。

此外，声网 Web SDK 还支持通过 `CameraVideoTrack.setDevice` 和 `MicrophoneAudioTrack.setDevice` 在创建轨道之后动态切换音视频采集设备。该方法支持在发布后调用，在部分移动设备上该方法可能不生效。

示例代码中的 `videoTrack` 是指通过 `AgoraRTC.createCameraVideoTrack` 创建的本地视频轨道对象。

```javascript
// 切换摄像头
videoTrack.setDevice("<NEW_DEVICE_ID>").then(() => {
  console.log("set device success");
}).catch(e => {
  console.log("set device error", e);
});
```

<a id="hot-plugging"></a>
### 音视频采集设备热插拔 [#音视频采集设备热插拔]

声网 Web SDK 提供 [`AgoraRTC.onMicrophoneChanged`](/zh-CN/api-reference/rtc/web/interfaces/iagorartc#onmicrophonechanged) 和 [`AgoraRTC.onCameraChanged`](/zh-CN/api-reference/rtc/web/interfaces/iagorartc#oncamerachanged) 回调，用于监听音视频设备的插拔状态。如果你想要在新设备插入的时候强制使用新设备，你需要监听 `AgoraRTC.onMicrophoneChanged` 或 `AgoraRTC.onCameraChanged`，并在对应的回调函数里调用 [`MicrophoneAudioTrack.setDevice`](/zh-CN/api-reference/rtc/web/interfaces/imicrophoneaudiotrack#setdevice) 或 [`CameraVideoTrack.setDevice`](/zh-CN/api-reference/rtc/web/interfaces/icameravideotrack#setdevice) 来切换音视频采集设备。

:::warning[注意]
如果终端用户使用了虚拟设备或故障设备，在进行设备拔插操作时，热拔插的逻辑可能会导致无画面或者无声。
:::

```javascript
AgoraRTC.onMicrophoneChanged = async (changedDevice) => {
  // 插入设备时，切换到新插入的设备
  if (changedDevice.state === "ACTIVE") {
    microphoneTrack.setDevice(changedDevice.device.deviceId);
    // 拔出设备为当前设备时，切换到一个已有的设备
  } else if (changedDevice.device.label === microphoneTrack.getTrackLabel()) {
    const oldMicrophones = await AgoraRTC.getMicrophones();
    oldMicrophones[0] && microphoneTrack.setDevice(oldMicrophones[0].deviceId);
  }
};

AgoraRTC.onCameraChanged = async (changedDevice) => {
  // 插入设备时，切换到新插入的设备
  if (changedDevice.state === "ACTIVE") {
    cameraTrack.setDevice(changedDevice.device.deviceId);
    // 拔出设备为当前设备时，切换到一个已有的设备
  } else if (changedDevice.device.label === cameraTrack.getTrackLabel()) {
    const oldCameras = await AgoraRTC.getCameras();
    oldCameras[0] && cameraTrack.setDevice(oldCameras[0].deviceId);
  }
};
```
