iOS

# 音频管理

Juphoon 音视频能力平台及终端的媒体引擎支持音频质量保障能力,Juphoon RTC SDK 提供视频通话过程中访客端实现音频管理的功能。

Juphoon 音视频能力平台及终端的媒体引擎支持音频质量保障能力,Juphoon RTC SDK 提供视频通话过程中访客端实现音频管理的功能。

# 1. 发送本地音频流

通话中的成员可通过调用 enableUploadAudioStream (opens new window) 方法来开启关闭发送本地音频流。

/**
 * 开启/关闭发送本地音频流
 *
 * - 调用该方法可开启或关闭发送本地音频流。开启后,房间成员将听见本端声音;关闭后,房间成员将听不见本端声音
 * - 房间中调用此方法不影响接收远端音频
 * - 初始化 JRTCRoom 时,默认不发送本地音频流。若要加入房间时,让房间内其他成员听见本端声音,需要在调用 {@link join:joinParam: join} 加入房间前设置
 * - 该方法在房间内和房间外均可调用,且在离开房间后该设置仍然有效。也就是说这一次设置了开启发送本地音频流,那么在下一次加入房间时默认会开启发送本地音频流
 * - 房间中也可调用此方法开启或关闭发送本地音频流,服务器会更新状态并同步给其他房间成员,即房间中所有成员都会收到 {@link JRTCRoomCallback.onParticipantUpdate:changeParam:room onParticipantUpdate} 回调
 *
 * @param enable 开启/关闭发送本地音频流
 * - true: 开启,即发送本地音频流
 * - false: 关闭,即不发送本地音频流
 * @return 接口调用结果
 * - true: 接口调用成功
 *  - 在调用此方法时,用户未加入房间,不会收到回调
 *  - 在调用此方法时,用户已在房间中,会收到 {@link JRTCRoomCallback.onRoomPropertyChanged:room: onRoomPropertyChanged} 回调
 * - false: 接口调用异常
 */
- (bool)enableUploadAudioStream:(bool)enable;
  1. 在多方通话中,enableUploadAudioStream (opens new window) 的作用是开启或关闭发送本地音频流。开启后,房间成员将听见本端声音;关闭后,房间成员将听不见本端声音。房间中调用此方法不影响接收远端音频。
  2. 初始化 JRTCRoom 时,默认不发送本地音频流。若要加入房间时让房间内其他成员听见本端声音,需要在调用 join (opens new window) 加入房间前设置,或者在JRTCRoomJoinParam (opens new window) 设置。
  3. 房间中调用此方法开启或关闭发送本地音频流,服务器会更新状态并同步给其他房间成员同时,房间中的其他成员会收到该成员“是否上传音频“的状态变化回调 onParticipantUpdate (opens new window)
  4. 此外,此方法还可以实现开启或关闭静音的功能。当 enable 值为 false ,将会停止发送本地音频流,此时其他成员将听不到您的声音,从而实现静音功能。
/**
 * 成员属性更新回调
 *
 * 当房间中有成员的属性发生变化时,房间中的其他成员会收到此回调,例如音频上传状态、视频上传状态、网络状态等发生变化。
 * @param participant JRTCRoomParticipant 成员对象
 * @param changeParam JRTCRoomParticipantChangeParam 更新标识类对象
 * @param room 当前 JRTCRoom 对象
 */
- (void)onParticipantUpdate:(JRTCRoomParticipant*)participant changeParam:(JRTCRoomParticipantChangeParam *)changeParam room:(JRTCRoom *)room;

示例代码:

// 发送音频流
[_room enableUploadAudioStream:true];

// 停止发送音频流
[_room enableUploadAudioStream:false];

// 成员状态改变通知
 */
- (void)onParticipantUpdate:(JRTCRoomParticipant*)participant participantChangeParam:(JRTCRoomParticipantChangeParam *)participantChangeParam room:(JRTCRoom *)room {
    if (changeParam.audio) {
     	// 成员音频上传状态发生改变
        if (participant.audio) {
         	// 该成员当前正在音频上传
        } else {
            // 该成员当前没有音频上传
        }
    }
}

# 2. 音频输出

/**
 * 开启/关闭音频输出
 *
 * - 该方法可实现本地静音功能。关闭时听不到房间内其他成员的声音,不影响其他成员;开启时可以听到其他成员声音
 * - 初始化 JRTCRoom 时,音频输出功能默认是开启的。若要加入房间时听不见其他成员的声音,建议在调用 {@link join:joinParam: join} 加入房间前设置
 * @param enable 是否开启音频输出
 * - true: 开启音频输出
 * - false: 关闭音频输出
 * @return 接口调用结果
 * - true: 接口调用成功,会收到 {@link JRTCRoomCallback.onRoomPropertyChanged:room: onRoomPropertyChanged} 回调
 * - false: 接口调用异常
 */
- (bool)enableAudioOutput:(bool)enable;
  1. 该方法可实现本地静音功能。关闭时听不到房间内其他成员的声音,不影响其他成员;开启时可以听到其他成员声音。
  2. 初始化 JRTCRoom (opens new window) 时,音频输出功能默认是开启的。若要加入房间时听不见其他成员的声音,建议在调用 join (opens new window) 加入房间前设置。
  3. 该方法可以关闭或重新开启音频输出功能,在房间内和房间外均可调用,且在离开房间后该设置仍然有效,也就是说这一次设置了关闭音频输出,那么下一次加入房间时也是默认关闭音频输出。
/**
 * 房间属性变化回调
 *
 * 当房间的属性发生变化时,会收到此回调,例如房间中有成员发起屏幕共享、录制状态发生变化等。
 *
 * @param changeParam JRTCRoomPropChangeParam 变化标识集合
 * @param room 当前 JRTCRoom 对象
 */
- (void)onRoomPropertyChanged:(JRTCRoomPropChangeParam *)changeParam room:(JRTCRoom *)room;

示例代码:

// 开启音频输出
[_room enableAudioOutput:true];

// 关闭音频输出
[_room enableAudioOutput:false];

// 房间状态发生改变通知
- (void)onRoomPropertyChanged:(JRTCRoomPropChangeParam *)changeParam room:(JRTCRoom *)room {
 	if (changeParam.audioOutput) {
     	// 音频输出状态发生改变   
        if (_room.audioOutput) {
         	// 当前音频为输出状态   
        } else {
         	// 当前音频未输出 
        }
    }
}

# 3. 自定义音频输入

通话中可以自定义从外部音频文件作为音频源输入,使用场景举例:比如共享本地音频。

/**
 * 开始/结束播放本地音频文件作为音频源输入
 *
 * @param enable     - true: 开始输入,当输入完成后会收到 {@link JRTCMediaDeviceCallback.onFileAudioInputDidFinish onFileAudioInputDidFinish} 回调通知
 *                - false: 结束输入,会收到 {@link JRTCMediaDeviceCallback.onFileAudioInputDidFinish onFileAudioInputDidFinish} 回调通知
 * @param filePath   音频文件路径,支持pcm,wav的格式(需要单声道,采样率16K音频文件)
 * @param loop       是否循环播放
 * @note 重复调用会覆盖
 * @return 接口调用结果
 * - true: 接口调用成功
 * - false: 接口调用异常
 */
- (bool)enableAudioInputFromFile:(bool)enable filePath:(NSString* __nullable)filePath loop:(bool)loop;

/**
 * 暂停/继续播放语音文件作为音频源输入
 *
 * @param suspend true 暂停播放 false 继续播放
 * @return  调用是否正常
 * - true: 正常执行调用流程
 * - false:调用异常
 */
- (bool)suspendAudioInputFromFile:(bool)suspend;

音频输入播放结束(非循环播放结束或者主动停止播放),会收到 JRTCMediaDeviceCallback 的 onFileAudioInputFinish 回调通知

/**
 * 本地文件音频源输入完成回调
 */
- (void)onFileAudioInputDidFinish;

示例代码:

// 开始分享本地文件音频输入到通话内
[_mediaDevice enableAudioInputFromFile:true filePath:@"/xxxxx/1.pcm" loop:true];
// 结束分享本地文件音频输入到通话内
[_mediaDevice enableAudioInputFromFile:false filePath:@"" loop:true];

- (void)onFileAudioInputDidFinish {
    // 分享本地文件音频输入到通话结束
}

# 4. 本地音频播放

通话中可以播放一段本地音频,使用场景举例:比如播放来电铃声。

/**
 * 开始播放音频
 *
 * - 当播放音频文件完成后会收到 {@link JRTCMediaDeviceCallback.onRingPlayFinish onRingPlayFinish} 回调通知
 * @param filePath 音频文件路径,支持pcm,wav的格式(需要单声道,采样率16K音频文件)
 * @param isLoop 是否循环播放
 * @return 播放音频结果
 * - true: 接口调用成功
 * - false: 接口调用异常
 */
- (bool)startRing:(NSString * _Nonnull)filePath isLoop:(bool)isLoop;

/**
 * 结束播放音频
 *
 * 会收到 {@link JRTCMediaDeviceCallback.onRingPlayFinish onRingPlayFinish} 回调通知
 * @return 关闭音频结果
 * - true: 接口调用成功
 * - false: 接口调用异常
 */
- (bool)stopRing;

音频播放结束会收到 JRTCMediaDeviceCallback (opens new window)onRingPlayFinish (opens new window) 回调通知

/**
 * 音频播放完成
 */
- (void)onRingPlayFinish;

示例代码:

// 开始播放本地音频
[_mediaDevice startRing:@"/xxxxx/1.pcm" isLoop:true];
// 结束播放本地音频
[_mediaDevice stopRing];

- (void)onRingPlayFinish {
    // 音频文件播放结束
}

# 5. 音频异常回调

通过实现 JRTCMediaDeviceCallback (opens new window)onAudioError (opens new window) 接口监听音频异常回调,具体错误查看参数 error 描述。

/**
 * 音频异常
 *
 * @param error 异常信息
 */
- (void)onAudioError:(NSString*)error;

# 6. 音频数据回调

# 输入音频数据回调

使用以下接口 setAudioInputFrameCallback (opens new window) 可以获取到本地音频输入数据回调,前提需要打开音频输入设备(麦克风)

/**
 * 设置音频输入帧回调
 * @param callback 原始音频数据输入回调代理对象
 */
- (void)setAudioInputFrameCallback:(id<AudioInputFrameCallback> _Nullable)callback;

/**
 * 音频输入数据回调
 */
@protocol AudioInputFrameCallback <NSObject>

/**
 * 获得采集的音频回调
 *
 * @param inputId      输入源的自定义字符串
 * @param sampleRateHz 输入源的采样频率
 * @param channels     输入源的频道数量
 * @param data         该帧的采样数据
 */
- (void)onFrame:(const char *_Nonnull)inputId sampleRateHz:(int)iSampleRateHz channels:(int)iChannels data:(NSData *_Nullable)data;

@end

示例代码:

@interface xxx ()<AudioInputFrameCallback> {
    
}

-(void)onFrame:(const char *)inputId sampleRateHz:(int)iSampleRateHz channels:(int)iChannels data:(NSData *)data {
    //音频输入数据回调
}

[_mediaDevice setAudioInputFrameCallback: self];

# 输出音频数据回调

如果需要房间内其他成员的音频输出数据回调,可以通过以下接口 setAudioOutputFrameCallback (opens new window) 设置回调接口

/**
 * 设置输出音频帧回调,传 nil 关闭回调
 *
 * @param callback 回调对象
 * @return
 * - true  设置成功
 * - false 设置失败
 */
- (void)setAudioOutputFrameCallback:(id<AudioOutputFrameCallback> _Nullable)callback;

/// 输出音频数据回调
@protocol AudioOutputFrameCallback <NSObject>

/**
 * 获得采集的音频回调
 *
 * @param data         10毫秒的实时PCM数据
 * @param length       PCM数据长度
 * @param sampleRateHz 输入源的采样频率
 * @param channels     输入源的频道数量
 */
- (void)onFrame:(NSData *_Nonnull)data length:(int)length sampleRateHz:(int)iSampleRateHz channels:(int)iChannels;

@end

示例代码:

//获取某个需要音频数据的成员对象
JRTCRoomParticipant *participant = [_room.participants objectAtIndex:0];

@interface xxx ()<AudioOutputFrameCallback> {
    
}

- (void)onFrame:(NSData *_Nonnull)data length:(int)length sampleRateHz:(int)iSampleRateHz channels:(int)iChannels; {
    //音频输出数据回调
}

[participant setAudioOutputFrameCallback: self];