音频常用操作和配置

更新时间:
复制 MD 格式

本文将为您介绍ARTC SDK中音频的常用操作和配置。

功能介绍

ARTC SDK中关于音频配置与操作的各项实用功能,涵盖从音频编码模式及音频场景模式的设置,到本地音频采集和播放管理、远端音频播放控制、耳返功能的应用,以及如何灵活设置音频路由等关键环节。

示例代码

Android端音频常用操作和配置:Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/AudioBasicUsage/AudioBasicUsageActivity.java。

iOS端音频常用操作和配置:iOS/ARTCExample/BasicUsage/AudioBasicUsage/AudioBasicUsageVC.swift。

Harmony端音频常用操作和配置:Harmony/ARTCExample/entry/src/main/ets/pages/basicusage/AudioBasicUsage.ets。

前提条件

功能实现

1.设置音频编码模式和场景模式(加入频道前)

image

ARTC SDK 提供setAudioProfile接口,支持设置不同的音频编码模式和音频场景模式。开发者可以根据不同的业务场景和用户需求,对音频的质量进行精准优化。

说明
  • setAudioProfile只可以在加入频道前调用,加入频道后不可以重新设置。

  • ARTC SDK 推荐使用 AliRtcEngineHighQualityMode 高音质编码模式和 AliRtcSceneMusicMode 音乐场景模式。

1.1.音频编码模式(AliRtcAudioProfile)

说明
  • 一般建议使用高音质模式(AliRtcEngineHighQualityMode)。

  • 如果需要与Web互通,需要选择采样率为 48k 的模式。

  • 如果需要双声道,建议设置为AliRtcEngineStereoHighQualityMode。

枚举名

描述

采样率

声道数

最大编码码率

AliRtcEngineLowQualityMode

音频低音质模式

8000Hz

单

12kbps

AliRtcEngineBasicQualityMode

标准音质模式

16000Hz

单

24kbps

AliRtcEngineHighQualityMode

高音质模式

48000Hz

单

64kbps

AliRtcEngineStereoHighQualityMode

立体声高音质模式

48000Hz

双

80kbps

AliRtcEngineSuperHighQualityMode

超高音质模式

48000Hz

单

96kbps

AliRtcEngineStereoSuperHighQualityMode

立体声超高音质模式

48000Hz

双

128kbps

1.2.音频场景模式(AliRtcAudioScenario)

枚举名

描述

AliRtcSceneDefaultMode

使用硬件 3A,可以从蓝牙设备采集,如果需要蓝牙采集可以设置为此模式。

AliRtcSceneMusicMode

(建议设置)音乐场景模式,使用软件 3A,从手机采集(音质更高)。

1.3.示例代码

以下将为您提供一些常见场景的音频编码模式及应用场景的模式设置示例。

需要蓝牙采集

Android

// 需要设置为AliRtcSceneDefaultMode场景
mAliRtcEngine.setAudioProfile(AliRtcEngineHighQualityMode, AliRtcSceneDefaultMode);

iOS

// 需要设置为AliRtcSceneDefaultMode场景
engine.setAudioProfile(AliRtcAudioProfile.engineHighQualityMode, audio_scene: AliRtcAudioScenario.sceneDefaultMode)

Harmony

this.rtcEngine.setAudioProfile(AliRtcAudioProfile.AliRtcHighQualityMode, AliRtcAudioScenario.AliRtcSceneDefaultMode);

Mac

[self.engine setAudioProfile:AliRtcEngineHighQualityMode audio_scene:AliRtcSceneDefaultMode];

Windows

mAliRtcEngine->SetAudioProfile(AliEngineHighQualityMode, AliEngineSceneDefaultMode);

需要与 Web 端互通

Android

// 需要设置为采样率48k的编码模式,例如AliRtcEngineHighQualityMode
mAliRtcEngine.setAudioProfile(AliRtcEngineHighQualityMode, AliRtcSceneMusicMode);

iOS

// 需要设置为采样率48k的编码模式,例如AliRtcEngineHighQualityMode
engine.setAudioProfile(AliRtcAudioProfile.engineHighQualityMode, audio_scene: AliRtcAudioScenario.sceneMusicMode)

Harmony

this.rtcEngine.setAudioProfile(AliRtcAudioProfile.AliRtcHighQualityMode, AliRtcAudioScenario.AliRtcSceneMusicMode);

Mac

[self.engine setAudioProfile:AliRtcEngineHighQualityMode audio_scene:AliRtcSceneMusicMode];

Windows

mAliRtcEngine->SetAudioProfile(AliEngineHighQualityMode, AliEngineSceneMusicMode);

需要双声道

Android

// 设置为带Stereo的模式,例如AliRtcEngineStereoHighQualityMode
mAliRtcEngine.setAudioProfile(AliRtcEngineStereoHighQualityMode, AliRtcSceneMusicMode);

iOS

// 设置为带Stereo的模式,例如AliRtcEngineStereoHighQualityMode
engine.setAudioProfile(AliRtcAudioProfile.engineStereoHighQualityMode, audio_scene: AliRtcAudioScenario.sceneMusicMode)

Harmony

this.rtcEngine.setAudioProfile(AliRtcAudioProfile.AliRtcStereoHighQualityMode, AliRtcAudioScenario.AliRtcSceneMusicMode);

Mac

[self.engine setAudioProfile:AliRtcEngineStereoHighQualityMode audio_scene:AliRtcSceneMusicMode];

Windows

mAliRtcEngine->SetAudioProfile(AliEngineStereoHighQualityMode, AliEngineSceneMusicMode);

2.本端音频采集设置

本节主要介绍如何控制本端音频采集,例如静音麦克风、关闭麦克风采集等,主要接口及区别如下:

接口

muteLocalMic

stopAudioCapture/startAudioCapture

实现原理

发送静音帧。

关闭/开启麦克风采集。

调用时机

加入频道前后均可调用。

加入频道后调用。

是否释放麦克风资源

否

是

2.1.静音麦克风

image

ARTC 提供muteLocalMic接口用于静音麦克风和外部输入音频,该接口可以在加入频道前后调用设置是否静音。

说明

与stopAudioCapture不同,调用muteLocalMic接口静音麦克风时,并没有释放麦克风资源,麦克风采集和编码模块仍在运行,仅是发送码率极低的静音帧。

支持设置的模式AliRtcMuteLocalAudioMode如下:

AliRtcMuteAudioModeDefault

默认模式,与AliRtcMuteAllAudioMode行为相同。

AliRtcMuteAllAudioMode

全部静音模式,麦克风采集与外部PCM输入都停止推送。

AliRtcMuteOnlyMicAudioMode

静音麦克风模式,只停止麦克风采集推送。

示例代码如下:

Android

// 静音全部
mAliRtcEngine.muteLocalMic(true, AliRtcEngine.AliRtcMuteLocalAudioMode.AliRtcMuteAllAudioMode);
// 取消静音全部
mAliRtcEngine.muteLocalMic(false, AliRtcEngine.AliRtcMuteLocalAudioMode.AliRtcMuteAllAudioMode);
// 仅静音麦克风
mAliRtcEngine.muteLocalMic(true, AliRtcEngine.AliRtcMuteLocalAudioMode.AliRtcMuteOnlyMicAudioMode);

iOS

// 静音全部
self.rtcEngine?.muteLocalMic(true, mode: .allAudioMode)
// 取消静音全部
self.rtcEngine?.muteLocalMic(false, mode: .allAudioMode)
// 仅静音麦克风
self.rtcEngine?.muteLocalMic(true, mode: .onlyMicAudioMode)

Harmony

// 静音全部
this.rtcEngine.muteLocalMic(true, AliRtcMuteLocalAudioMode.AliRtcMuteLocalAudioModeMuteAll);
// 取消静音全部
this.rtcEngine.muteLocalMic(false, AliRtcMuteLocalAudioMode.AliRtcMuteLocalAudioModeMuteAll);
// 仅静音麦克风
this.rtcEngine.muteLocalMic(true, AliRtcMuteLocalAudioMode.AliRtcMuteLocalAudioModeMuteOnlyMic);

Mac

// 静音全部
[self.engine muteLocalMic:TRUE mode:AliRtcMuteAllAudioMode];
// 取消静音全部
[self.engine muteLocalMic:FALSE mode:AliRtcMuteAllAudioMode];
// 仅静音麦克风
[self.engine muteLocalMic:TRUE mode:AliRtcMuteOnlyMicAudioMode];

Windows

// 静音全部
mAliRtcEngine->MuteLocalMic(true, AliEngineMuteLocalAudioModeMuteAll);
// 取消静音全部
mAliRtcEngine->MuteLocalMic(false, AliEngineMuteLocalAudioModeMuteAll);
// 仅静音麦克风
mAliRtcEngine->MuteLocalMic(true, AliEngineMuteLocalAudioModeMuteOnlyMic);

2.2.关闭/恢复麦克风采集

SDK 加入频道默认开启麦克风采集,如果需要关闭麦克风采集,可以调用stopAudioCapture停止麦克风采集,此接口会释放麦克风资源停止采集音频。如果需要恢复麦克风采集,请调用startAudioCapture接口。

Android

// 停止麦克风采集
mAliRtcEngine.stopAudioCapture();
// 恢复麦克风采集
mAliRtcEngine.startAudioCapture();

iOS

// 停止麦克风采集
self.rtcEngine?.stopAudioCapture()
// 恢复麦克风采集
self.rtcEngine?.startAudioCapture()

Harmony

// 停止麦克风采集
this.rtcEngine.stopAudioCapture();
// 恢复麦克风采集
this.rtcEngine.startAudioCapture();

Mac

// 停止麦克风采集
[self.engine stopAudioCapture];
// 恢复麦克风采集
[self.engine startAudioCapture];

Windows

// 停止麦克风采集
mAliRtcEngine->StopAudioCapture();
// 恢复麦克风采集
mAliRtcEngine->StartAudioCapture();

3.远端音频播放设置

本节将介绍如何控制远端用户音频的播放。

3.1.静音远端用户

ARTC 提供muteRemoteAudioPlaying接口停止/恢复远端指定用户音频播放,接口定义如下:

public abstract int muteRemoteAudioPlaying(String uid, boolean mute);
  • 这里的静音不影响音频拉流和解码,可以在入会前后设置。

  • 这里的静音仅影响远端用户音频在本端的播放,不影响远端用户采集。

3.2.设置指定远端用户播放音量

ARTC 提供setPlayoutVolume接口控制本端播放音量。

/**
 * @brief 设置播放音量
 * @param volume 播放音量,取值范围[0,400]
 * - 0:静音
 * - <100:减小音量
 * - >100:放大音量
 * @return
 * - 0: 成功
 * - 非0: 失败
 */
public abstract int setPlayoutVolume(int volume);

ARTC 提供setRemoteAudioVolume接口用于控制指定的远端用户音频播放音量,当传入 volume 参数为 0 时等同于muteRemoteAudioPlaying接口。

/**
 * @brief 调节本地播放的指定远端用户音量
 * @param uid 用户ID,从App server分配的唯一标示符
 * @param volume 播放音量,取值范围[0,100] 0:静音;100:原始音量
 * @return
 * - 0: 成功
 * - 非0: 失败
 */
public abstract int setRemoteAudioVolume(String uid, int volume);

4.耳返功能

耳返功能指通过耳机监听麦克风采集的声音。

4.1.开启耳返

可以在加入频道前后调用enableEarBack接口开启耳返功能。如果需要关闭耳返功能,请再次调用enableEarBack并将参数置为 false。

说明

建议戴耳机的情况下开启耳返。

Android

rtcEngine.enableEarBack(true);

iOS

engine.enableEarBack(true)

Harmony

this.rtcEngine.enableEarBack(true);

Mac

[self.engine enableEarBack:YES];

Windows

mAliRtcEngine->EnableEarBack(TRUE);

4.2.设置耳返音量

调用setEarBackVolume接口调整耳返的音量,参数volume表示音量大小,范围为 [0~100],其中 0 表示静音,100 表示正常音量,默认值为 100。

Android

rtcEngine.setEarBackVolume(60);

iOS

rtcEngine?.setEarBackVolume(volume)

Harmony

this.rtcEngine.setEarBackVolume(value);

Mac

[self.engine setEarBackVolume:60];

Windows

mAliRtcEngine->SetEarBackVolume(volume);

5.用户音量回调及说话人回调

image

ARTC 提供了用户音量回调和说话人(当前活跃的发言人)回调,便于应用实时感知用户的发言状态。

说明

该功能默认关闭,需要调用enableAudioVolumeIndication接口开启该功能,功能开启后系统会按照设置的频率周期性地上报每位用户的实时音量与当前说话人,开发者可根据此实现 UI 交互。

5.1. 开启回调功能

调用enableAudioVolumeIndication 开启功能并设置回调频率、平滑系数等,参数如下:

  • interval:回调频率间隔,单位为 ms。建议设置为 300~500ms,最小不能低于 10ms,如果设置为负值表示关闭此功能。

  • smooth:平滑系数,数值越大表示平滑程度越高,反之平滑程度低实时性好,建议设置为 3,取值范围为 [0-9]。

  • reportVad:说话人检测开关,0 表示关闭,1 表示开启。

Android

mAliRtcEngine.enableAudioVolumeIndication(500, 3,1);

iOS

// 用户音量回调和说话人检测
engine.enableAudioVolumeIndication(500, smooth: 3, reportVad: 1)

Harmony

// 用户音量回调和说话人检测
this.rtcEngine.enableAudioVolumeIndication(1000, 3, 1);

Mac

// 用户音量回调和说话人检测
[self.engine enableAudioVolumeIndication:500 smooth:3 reportVad:1];

Windows

// 用户音量回调和说话人检测
mAliRtcEngine->EnableAudioVolumeIndication(500, 3, 1);

5.2. 实现并注册相关回调

调用registerAudioVolumeObserver接口注册相关回调,之后系统会根据设置的间隔回调:

  • onAudioVolume 回调负责提供周期性的音频音量信息,用于实时掌握各用户的发言强度。系统会定时上报当前检测到的所有用户(包括本地和远端)的音量级别,开发者可用于实现声波动画、音量指示条或静音检测等 UI 反馈。其中,当 mUserId 为 "0" 时,表示该条目为本地采集音量;mUserId 为“1”时表示所有远端用户的混音音量,其他值表示指定用户的音量信息。 totalVolume 表示所有远端用户混音后的总体音量。

  • onActiveSpeaker 是语音激励(Voice Activity Detection, VAD)触发的主讲人回调。当系统检测到某个用户成为当前最活跃的发言人(说话音量和持续时间超过阈值)时,会通过此回调通知应用层。开发者可利用该事件实现“自动聚焦发言人”的交互体验,例如会议场景讲说话人视频窗口置为大屏等。

Android

private final AliRtcEngine.AliRtcAudioVolumeObserver mAliRtcAudioVolumeObserver = new AliRtcEngine.AliRtcAudioVolumeObserver() {
    // 用户音量回调
    @Override
    public void onAudioVolume(List<AliRtcEngine.AliRtcAudioVolume> speakers, int totalVolume){
        handler.post(() -> {
            if(!speakers.isEmpty()) {
                for(AliRtcEngine.AliRtcAudioVolume volume : speakers) {
                    if("0".equals(volume.mUserId)) {
                        // 本地当前用户音量

                    } else if ("1".equals(volume.mUserId)) {
                        // 远端用户整体音量

                    } else {
                        // 远端用户音量

                    }
                }
            }
        });
    }

    // 说话人检测回调
    @Override
    public void onActiveSpeaker(String uid){
        // 说话人
        handler.post(() -> {
            String mag = "onActiveSpeaker uid:" + uid;
            ToastHelper.showToast(AudioBasicUsageActivity.this, mag, Toast.LENGTH_SHORT);
        });
    }
};
// 注册回调
mAliRtcEngine.registerAudioVolumeObserver(mAliRtcAudioVolumeObserver);

iOS

说明

ios 不需要调用注册回调接口,只需要实现相关回调即可:

  • 0nAudioVolumeCallback

  • onActiveSpeaker

func onAudioVolumeCallback(_ array: [AliRtcUserVolumeInfo]?, totalVolume: Int32) {
    // 用户音量回调
    "onAudioVolumeCallback, totalVolume: \(totalVolume)".printLog()
}

func onActiveSpeaker(_ uid: String) {
    // 说话人回调
    "onActiveSpeaker, uid: \(uid)".printLog()
}

Harmony

this.rtcEngineEventListener.onAudioVolumeCallback(
  (volumeInfo : AliRtcUserVolumeInfo[], volumeInfoCount : number, totalVolume : number) => {
    console.info(`音量回调: volumeInfo=${volumeInfo}, volumeInfoCount=${volumeInfoCount}, totalVolume=${totalVolume}`);
  }
)

this.rtcEngineEventListener.onActiveSpeaker((uid: string) => {
  console.info(`当前活动用户: uid=${uid}`);
});

Mac

- (void)onAudioVolumeCallback:(NSArray <AliRtcUserVolumeInfo *> *)array totalVolume:(int)totalVolume {
    for(AliRtcUserVolumeInfo *info in array) {
        NSString *uid = info.uid;
        NSInteger volume = info.volume;
        dispatch_async(dispatch_get_main_queue(), ^{
            NSArray * volumeArray = [ _audioVolumeLabel.stringValue componentsSeparatedByString:@"\n"];

            if ([uid isEqualToString:@"1"]) { //远端音量
                //远端音量整体值
            }else if ([uid isEqualToString:@"0"] ){ //本地音量
                //本地音量显示
            } else {

                // 远端用户整体音量
            }
        });
    }
}

- (void)onActiveSpeaker:(NSString *)uid {
    if ([uid isEqualToString:@"0"]) {
        [self log:[@"说话人:自己" UTF8String]];
    } else {
        NSDictionary *dic = [self.engine getUserInfo:uid];
        NSString *name = dic[@"displayName"];
        MyLog(@"说话人:%@",name);
    }
}

Windows

void CTutorialDlg::OnAudioVolumeCallback(const AliEngineUserVolumeInfo* volumeInfo, int volumeInfoCount, int totalVolume)
{
	CArray<AliEngineUserVolumeInfo*>* pArray = new CArray<AliEngineUserVolumeInfo*>;
	for (int i = 0; i < volumeInfoCount; i++)
	{
		AliEngineUserVolumeInfo* p = new AliEngineUserVolumeInfo;
		p->uid = volumeInfo[i].uid;
		p->volume = volumeInfo[i].volume;
		p->speechState = volumeInfo[i].speechState;
		p->sumVolume = volumeInfo[i].sumVolume;
		pArray->Add(p);
	}
    /* 通知UI刷新 */
	PostMessage(MM_VOLUME_CALLBACK, (WPARAM)totalVolume, (LPARAM)pArray);
}

void CTutorialDlg::OnActiveSpeaker(const char *uid)
{
	m_strCurSpeaker = CString(uid);
    /* 通知UI刷新  */
	PostMessage(MM_ACTIVE_SPEAKER, NULL, NULL);
}

6.设置音频路由

音频路由(Audio Route)作为音频设备管理中的重要组成模块,用于判断和调整当前通话过程中声音播放的音频设备。设备类型主要包含:

  • 内置播放设备:一般包括扬声器和听筒。

    • 当音频路由为扬声器时,声音比较大,不用将手机贴脸也能听清,因此可以实现“免提”的功能。

    • 当音频路由为听筒时,声音比较小,只有将耳朵凑近才能听清楚,隐私性较好,适合用于接听电话。

  • 外接设备:涵盖有线耳机、蓝牙耳机等外部音频设备,以及外置声卡等专业音频接口。

音频路由的优先级在SDK内部已经定义好,并会根据当前外设的连接状态自动切换,切换的流程图如下所示:

image

6.1.默认音频路由

默认音频路由用于在入会前设置默认的音频路由设备,在听筒和扬声器之间选择。如果没有设置该功能,将默认使用扬声器。

说明
  • 当连接的蓝牙耳机和有线耳机等其他外设断开连接时,将使用该功能设置的设备进行播放。

  • 当没有外置设备,且用户没有设置当前设备,则使用 SDK 默认设置。SDK 默认使用扬声器作为输出,如果需要修改此默认设置,可以调用setDefaultAudioRoutetoSpeakerphone切换默认设置。

/**
* @brief 设置默认音频输出是否从扬声器出声,默认从扬声器出声
* @param defaultToSpeakerphone
* - true: 扬声器模式(默认扬声器)
* - false: 听筒模式
* @return
* - 0: 成功
* - <0: 失败
*/
public int setDefaultAudioRoutetoSpeakerphone(boolean defaultToSpeakerphone);

6.2.当前音频路由

当前音频路由用于在会议当中设置当前播放的音频设备,在听筒和扬声器之间选择。如果没有设置该功能, 将使用默认音频路由所设置的设备进行播放。

说明

在连接有线耳机或者蓝牙耳机等其他外设的情况下,该函数调用不生效。

在没有外置设备的情况下,用户可以调用enableSpeakerphone设置当前是否使用扬声器,设置为否则使用听筒。如果需要检查当前的音频设备为扬声器或听筒,可以调用isSpeakerOn接口。

/**
 * @brief 设置音频输出为听筒还是扬声器
 * @param enable   true:扬声器模式(默认扬声器);false:听筒模式
 * @return
 * - 0: 成功
 * - <0: 失败
 */
public int enableSpeakerphone(boolean enable);
/**
* @brief 获取当前音频输出为听筒还是扬声器
* @return 
* - true: 扬声器模式;
* - false: 听筒模式
*/
public boolean isSpeakerOn();

6.3.音频路由设备变化回调

如果想获取音频播放设备切换时的回调需要注册并监听以下回调。

public abstract class AliRtcEngineEventListener {
    /**
     * @brief 警告通知
     * @details 如果engine出现warning,通过这个回调通知app
     * @param warn 警告类型
     * @param message 警告消息
     */
    public void onOccurWarning(int warn, String message);
}

warn返回值和设备类型对应关系如下表:

返回值

设备

1

有线有麦耳机

2

听筒

3

有线无麦耳机

4

扬声器

6

SCO 蓝牙设备

7

A2DP 蓝牙设备