目录

Switching Audio Input Devices

Starting from API version 21, support for switching audio input device routes is available.

When an application performs audio input, the system selects the corresponding input device based on the audio stream type. (If the audio stream type is SOURCE_TYPE_MIC, the built-in microphone is used for recording. If the audio stream type is SOURCE_TYPE_VOICE_COMMUNICATION, the input device follows the current output device.) If the default input device does not meet the application requirements, the application can call setBluetoothAndNearlinkPreferredRecordCategory or selectMediaInputDevice to switch the audio input device.

Starting from API version 26.0.0, PCs/2-in-1 devices also support input device switching based on AudioDeviceEnhanceManager and native_audio_device_enhance_manager.h. You can specify the input device precisely at the application level or audio stream level to control the audio capture source in multi-device scenarios.

The code snippets in the following steps are fragments. You can obtain the complete sample from the link at the lower right of the sample code. For the complete sample of input device switching on PCs/2-in-1 devices, see the ArkTS sample and C/C++ sample.

Manually Selecting Input Devices

Applications can use selectMediaInputDevice of AudioSessionManager to select an input device.

In call scenarios, the input device follows the current output device, and other concurrent recording streams also follow the call input device.

import { audio } from '@kit.AudioKit';
import { BusinessError } from '@kit.BasicServicesKit';
// ...

let audioManager = audio.getAudioManager();
let audioSessionManager = audioManager.getSessionManager();
// ...

  try {
    // Listen for the current input device change event. This callback is triggered after an input device is successfully selected.
    audioSessionManager.on('currentInputDeviceChanged', (currentInputDeviceChangedEvent: audio.CurrentInputDeviceChangedEvent) => {
      console.info(`Succeeded in using on function. CurrentInputDeviceChangedEvent: ${JSON.stringify(currentInputDeviceChangedEvent)}`);
      // ...
    });
  } catch (err) {
    let error = err as BusinessError;
    console.error(`Failed to use on function. Code: ${error.code}, message: ${error.message}`);
    // ...
  }
  // ...

  try {
    // Listen for the connection status change event of available audio input devices. A callback notification is received when an input device goes online or offline.
    audioSessionManager.on('availableDeviceChange', audio.DeviceUsage.MEDIA_INPUT_DEVICES, (deviceChanged: audio.DeviceChangeAction) => {
      console.info(`Succeeded in using on function. DeviceChangeAction: ${JSON.stringify(deviceChanged)}`);
      // ...
    });
  } catch (err) {
    let error = err as BusinessError;
    console.error(`Failed to use on function. Code: ${error.code}, message: ${error.message}`);
    // ...
  }
  // ...

  try {
    // Obtain the list of currently available audio input devices.
    let data = audioSessionManager.getAvailableDevices(audio.DeviceUsage.MEDIA_INPUT_DEVICES);
    console.info(`Succeeded in getting available devices. AudioDeviceDescriptors: ${JSON.stringify(data)}`);
    // You can select a device when the list of available audio input devices is not empty.
    if (data[1] || data[0]) {
      // Select an input device.
      audioSessionManager.selectMediaInputDevice(data[1] ? data[1] : data[0]).then(() => {
        console.info('Succeeded in selecting media input device.');
        // ...
      }).catch((err: BusinessError) => {
        console.error(`Failed to select media input device. Code: ${err.code}, message: ${err.message}`);
        // ...
      });
    }
  } catch (err) {
    let error = err as BusinessError;
    console.error(`Failed to getAvailableDevices. Code: ${error.code}, message: ${error.message}`);
    // ...
  }
  // ...

  try {
    // You can query whether the input device selection is successful through this API.
    let device = audioSessionManager.getSelectedMediaInputDevice();
    console.info(`Succeeded in getting selected media input device. Device: ${JSON.stringify(device)}`);
    // ...
  } catch (err) {
    let error = err as BusinessError;
    console.error(`Failed to get selected media input device. Code: ${error.code}, message: ${error.message}`);
    // ...
  }
  // ...

  // Clear the input device selected via selectMediaInputDevice.
  audioSessionManager.clearSelectedMediaInputDevice().then(() => {
    console.info('Succeeded in clearing selected media input device.');
    // ...
  }).catch((err: BusinessError) => {
    console.error(`Failed to clear selected media input device. Code: ${err.code}, message: ${err.message}`);
    // ...
  });

Input Device Switching on PCs/2-in-1 Devices

PCs/2-in-1 devices often have multiple input devices available (such as the built-in microphone and USB/Bluetooth headset microphones). The system default device selection policy may not meet the input requirements of applications in various scenarios. With this capability, you can precisely specify the input device at the application level or audio stream level, meeting the requirement for controlling the audio capture source in multi-device scenarios.

[h2]Checking Whether the Capability Is Supported

Before use, call isEnhancedRoutingSupported or OH_AudioDeviceEnhanceManager_IsEnhancedRoutingSupported to check whether the system supports this capability. If the capability is not supported, calling the input device switching APIs does not take effect, and the current input device continues to be used.

ArkTS sample code:

import { audio } from '@kit.AudioKit';
import { BusinessError } from '@kit.BasicServicesKit';
// ...
  let audioManager = audio.getAudioManager();
  let audioDeviceEnhanceManager: audio.AudioDeviceEnhanceManager = audioManager.getDeviceEnhanceManager();
  // Query whether the system supports the enhanced routing capability provided by the current manager.
  let isSupported: boolean = audioDeviceEnhanceManager.isEnhancedRoutingSupported();
  console.info(`Succeeded in querying whether enhanced routing is supported. Result: ${isSupported}.`);

C/C++ example:

Add the following header files before use:

#include <ohaudio/native_audio_device_enhance_manager.h>
#include <ohaudio/native_audio_routing_manager.h>
#include <ohaudio/native_audio_device_base.h>
#include <ohaudio/native_audiocapturer.h>
#include <ohaudio/native_audiorenderer.h>
#include <ohaudio/native_audiostreambuilder.h>
napi_value IsEnhancedRoutingSupported(napi_env env, napi_callback_info info)
{
    OH_AudioDeviceEnhanceManager *enhanceManager = nullptr;
    OH_AudioCommon_Result result = OH_AudioManager_GetAudioDeviceEnhanceManager(&enhanceManager);
    bool isSupported = false;
    // Query whether the system supports the enhanced routing capability provided by the current manager.
    result = OH_AudioDeviceEnhanceManager_IsEnhancedRoutingSupported(enhanceManager, &isSupported);
    // ...
}

[h2]Switching Input Devices

Input device switching supports two granularities: application level and audio stream level. The application level takes effect on all recording streams under an application, while the audio stream level takes effect only on a specified recording stream. The audio stream level has a higher priority than the application level.

If a recording stream has been assigned a dedicated input device through an audio stream-level API, that stream uses its dedicated input device, while other recording streams in the application still use the input device set at the application level or the system default input device.

ArkTS sample code:

C/C++ example: