声网调研
Agora互动直播:可实现一对多,多对多的音视频互动直播。
互动直播和视频通话的区别:
- 视频通话,不区分主播和观众,所有用户都可以自由发言,默认流畅和低延时,画质稍低。
- 互动直播,用户区分主播和观众,只有主播可以自由发言,默认画质高。
基础互动直播接入
准备环境
1.创建iOS项目
2.集成SDK
3.配置工程文件
互动直播:
1.创建用户界面
2.导入类
3.初始化AgoraRtcEngineKit:
- (void)initializeAgoraEngine {
self.agoraKit = [AgoraRtcEngineKit sharedEngineWithAppId:appID delegate:self];
}
4.设置频道:
[self.rtcEngine setChannelProfile:AgoraChannelProfileLiveBroadcasting];
AgoraChannelProfile 直播模式:
- AgoraChannelProfileCommunication:通话模式,用于常见的一对一或群聊,频道中的任何用户可以自由说话。
- AgoraChannelProfileLiveBroadcasting:直播模式,直播模式有主播和观众两种用户角色,可以通过调用 setClientRole 设置。主播可收发语音和视频,但观众只能收,不能发。
- AgoraChannelProfileGame:游戏语音模式,该模式仅可在 Agora Gaming SDK 中使用,频道内任何用户可自由发言。该模式下默认使用低功耗低码率的编解码器。
5.设置用户角色:
[self.rtcEngine setClientRole:AgoraClientRoleAudience];
AgoraClientRole用户角色:
- AgoraClientRoleAudience:观众(默认)
- AgoraClientRoleBroadcaster:主播
6.设置本地视图:
- 调用 enableVideo 方法启用视频模块。
- 调用 setupLocalVideo 方法设置本地视图。
[self.agoraKit enableVideo];
- (void)setupLocalVideo {
AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
videoCanvas.uid = 0;
videoCanvas.view = self.localVideo;
videoCanvas.renderMode = AgoraVideoRenderModeHidden;
// 设置本地视图。
[self.agoraKit setupLocalVideo:videoCanvas];
}
7.加入频道:
调用joinChannelByToken方法加入频道:
- channelId: 传入能标识频道的频道 ID。
- token: 传入能标识用户角色和权限的 Token。
- uid: 本地用户的 ID。
- joinSuccessBlock:成功加入频道回调。注:joinSuccessBlock 优先级高于 didJoinChannel,2 个同时存在时,didJoinChannel 会被忽略。 需要有 didJoinChannel 回调时,请将 joinSuccessBlock 设置为 nil。
- (void)joinChannel {
// 加入频道。
[self.agoraKit joinChannelByToken:token channelId:@"demoChannel1" info:nil uid:0 joinSuccess:^(NSString *channel, NSUInteger uid, NSInteger elapsed) {
}];
}
8.设置远端视图:
调用 setupRemoteVideo 方法设置远端用户的视图。
远端用户成功加入频道后,SDK 会触发 firstRemoteVideoDecodedOfUid 回调,该回调中会包含这个远端用户的 uid 信息。在该回调中调用 setupRemoteVideo 方法,传入获取到的 uid,设置远端用户的视图。
- (void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoDecodedOfUid:(NSUInteger)uid size: (CGSize)size elapsed:(NSInteger)elapsed {
if (self.remoteVideo.hidden) {
self.remoteVideo.hidden = NO;
}
AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
videoCanvas.uid = uid;
videoCanvas.view = self.remoteVideo;
videoCanvas.renderMode = AgoraVideoRenderModeHidden;
// 设置远端视图。
[self.agoraKit setupRemoteVideo:videoCanvas];
}
9.离开频道:
调用 leaveChannel 离开当前通话频道。
[self.rtcEngine setupLocalVideo:nil];
// 离开频道。
[self.rtcEngine leaveChannel:nil];
if (self.isBroadcaster) {
[self.rtcEngine stopPreview];
}
信令功能
信令功能用户直播内的学生与老师之间的交互任务。
准备环境
1.获取AppID
2.穿件项目
3.集成SDK
信令与通道
初始化
调用 initWithAppId 方法创建一个实例。在该方法中:
- 填入获取到的 App ID。只有 App ID 相同的应用程序才能互通。
- 指定一个事件回调。SDK 通过回调通知应用程序 SDK 的状态变化和运行事件等。
@interface ViewController ()
@property(nonatomic, strong)AgoraRtmKit* kit;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 创建一个 AgoraRtmKit 实例
_kit = [[AgoraRtmKit alloc] initWithAppId:YOUR_APP_ID delegate:self];
}
登录
调用 loginByToken 方法登录RTM服务器。在该方法中:
- 传入能标识用户角色和权限的 token。如果安全要求不高,也可以将值设为 "nil"。token 需要在应用程序的服务器端生成。
- 传入能标识每个用户 ID。usedId 为字符串,必须是可见字符(可以带空格),不能为空或者多于 64 个字符,也不能是字符串 nil。
- 传入结果回调,用于接收登录 RTM 服务器成功或者失败的结果回调。
[_kit loginByToken:nil user:@"testuser" completion:^(AgoraRtmLoginErrorCode errorCode) {
if (errorCode != AgoraRtmLoginErrorOk) {
NSLog(@"login failed %@", @(errorCode));
} else {
NSLog(@"login success");
}
}];
#pragma AgoraRtmDelegate
...
- (void)rtmKit:(AgoraRtmKit *)kit connectionStateChanged:(AgoraRtmConnectionState)state reason:(AgoraRtmConnectionChangeReason)reason
{
NSLog(@"Connection state changed to %@", @(reason));
}
退出登录,调用 logoutWithCompletion 方法
[_kit logoutWithCompletion:^(AgoraRtmLogoutErrorCode errorCode) {
if (errorCode != AgoraRtmLogoutErrorOk) {
NSLog(@"logout failed %@", @(errorCode));
} else {
NSLog(@"logout success");
}
}];
点对点消息
发送点对点消息
调用 sendMessage 方法发送点对点消息。在该方法中:
- 传入目标消息接收方的用户账号 ID。
- 传入 AgoraRtmMessage 对象实例。该消息对象由 AgoraRtmMessage 类的 initWithText 初始化方法创建和设置消息内容。
- 传入消息发送状态监听器,用于接收消息发送结果回调。
- (void)... {
[_kit sendMessage:[[AgoraRtmMessage alloc] initWithText:@"testmsg"] toPeer:@"peer" completion:^(AgoraRtmSendPeerMessageState state) {
if (state == AgoraRtmSendPeerMessageStateReceivedByPeer) {
NSLog(@"Message successfully sent.");
}
}];
}
#pragma AgoraRtmDelegate
- (void)rtmKit:(AgoraRtmKit *)kit messageReceived:(AgoraRtmMessage *)message fromPeer:(NSString *)peerId
{
NSLog(@"Message received from %@: %@", message.text, peerId);
}
接收点对点消息
- (void)rtmKit:(AgoraRtmKit *)kit messageReceived:(AgoraRtmMessage *)message fromPeer:(NSString *)peerId
{
NSLog(@"Message received from %@: %@", message.text, peerId);
}
频道消息
App 在成功登录 RTM 服务器之后,可以开始使用 RTM 的频道消息功能。
创建并加入频道
调用 AgoraRtmChannel 实例的 createChannelWithId 方法创建 AgoraRtmChannel 实例。在该方法中:
- 传入能标识每个频道的 ID。channelId 为字符串,必须是可见字符(可以带空格),不能为空或者多于 64 个字符,也不能是字符串 "nil"。
- 指定一个事件回调。SDK 通过回调通知应用程序频道的状态变化和运行事件等,如: 接收到频道消息、用户加入和退出频道等。
用户只有在加入频道之后,才能收发频道消息和获取频道成员列表等。调用 AgoraRtmChannel 实例的 joinWithCompletion 方法加入频道。在该方法中,指定回调用于判断是否成功加入该频道。
@interface ViewController ()
...
@property(nonatomic, strong)AgoraRtmChannel* channel;
@implementation
- (void)... {
_channel = [_kit createChannelWithId:@"testchannel" delegate:self];
[_channel joinWithCompletion:^(AgoraRtmJoinChannelErrorCode state) {
if(state == AgoraRtmJoinChannelErrorOk) {
NSLog(@"join success");
} else {
NSLog(@"join failed: %@", @(state));
}
}];
}
#pragma AgoraRtmChannelDelegate
- (void)channel:(AgoraRtmChannel *)channel memberLeft:(AgoraRtmMember *)member
{
NSLog(@"%@ left channel %@", member.userId, member.channelId);
}
- (void)channel:(AgoraRtmChannel *)channel memberJoined:(AgoraRtmMember *)member
{
NSLog(@"%@ joined channel %@", member.userId, member.channelId);
}
接收频道消息
- (void)channel:(AgoraRtmChannel *)channel messageReceived:(AgoraRtmMessage *)message fromMember:(AgoraRtmMember *)member
{
NSLog(@"message received from %@ in channel %@: %@", message.text, member.channelId, member.userId);
}
退出频道
[_channel leaveWithCompletion:^(AgoraRtmLeaveChannelErrorCode state) {
if(state == AgoraRtmLeaveChannelErrorOk) {
NSLog(@"leave success");
} else {
NSLog(@"leave failed: %@", @(state));
}
}];
直播进阶功能
频道
1.快速切换频道:
互动直播过程中,观众加入频道后只需调用 switchChannelByToken 方法,就可以快速切换到另外一个直播频道。
成功调用 switchChannelByToken 方法切换到其他频道后,本地会先收到离开原频道的回调 didLeaveChannel,再收到成功加入新频道的回调 didJoinChannel。
2.获取频道的连接状态:
connectionChangedToState 回调。当用户连接状态发生改变时,SDK 会触发该回调,并在回调中明确当前的连接状态和发生状态改变的原因。
该回调下,SDK 有以下连接状态:
* DISCONNECTED(1):连接断开
* CONNECTING(2):建立网络连接中
* CONNECTED(3):网络已连接
* RECONNECTING(4):重新建立网络连接中
* FAILED(5):网络连接失败
通信过程中,如果 SDK 因网络等原因,断开与服务器的连接,SDK 会自动开启断线重连机制。
音频
音量
1.设置采集音量(麦克风音量):
调节音量的参数值范围是 0 - 400,默认值 100 表示原始音量。
[agoraKit adjustRecordingSignalVolume: 50];
2.设置播放音量:
调节音量的参数值范围是 0 - 400,默认值 100 表示原始音量。
[agoraKit adjustPlaybackSignalVolume: 50];
3.设置混音音量:
混音是指播放本地或者在线音乐文件,同时让频道内的其他人听到此音乐。
// 设置远端用户听到的音乐文件音量
[agoraKit adjustAudioMixingPublishVolume: 50];
// 设置本地用户听到的音乐文件音量
[agoraKit adjustAudioMixingPlayoutVolume: 50];
也可以直接调用 adjustAudioMixingVolume,同时设置本地及远端用户听到的音乐文件音量。
[agoraKit adjustAudioMixingVolume: 50];
4.设置音效音量
播放音效是指播放短小的音频,如鼓掌、子弹撞击的声音等。调节音效音量的参数值范围是 0.0 - 100.0,默认值 100.0 表示原始音效音量。
// 设置所有音效文件的播放音量
[agoraKit setEffectsVolume: 50.0];
// 设置单个音效文件的播放音量
// soundId 是你在调用 playEffect 时设置的音效 ID
[agoraKit setVolumeOfEffect: soundId:@"1" volume:50.0];
5.设置耳返音量
在音频采集、混音、播放的整个过程中,使用 setInEarMonitoringVolume 调整耳返的音量。
// 开启耳返监听功能
[agoraKit enableInEarMonitoring(YES)];
// 设置耳返音量
[agoraKit setInEarMonitoringVolume: 50];
6.获取用户音量(回调方法)
- (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine reportAudioVolumeIndicationOfSpeakers:(NSArray *_Nonnull)speakers totalVolume:(NSInteger)totalVolume {
// 获取瞬时说话音量最大的几个用户 ID
// speakers 为一个数组,包含说话者的用户 ID 及音量,音量范围为 0 - 255
// totalVolume 指混音后频道内的总音量,范围为 0 - 255
}
当前时间内累积音量最大者。
- (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine activeSpeaker:(NSUInteger)speakerUid {
// 获取当前时间段声音最大的用户 ID(仅 1 个)
}
开关
方法 | 功能 |
---|---|
enableAudio | 启用音频模块 |
disableAudio | 关闭音频模块 |
enableLocalAudio | 开关本地音频采集 |
muteLocalAudioStream | 开关本地音频发送 |
muteRemoteAudioStream | 停止/恢复接收指定音频流 |
muteAllRemoteAudioStreams | 停止/恢复接收所有音频流 |
音频属性
setAudioProfile 方法给开发者根据场景需求灵活配置适合的音质属性。
参数 | 描述 |
---|---|
profile | 代表不同的音频参数配置(音质),比如采样率、码率和编码模式等: * AgoraAudioProfileDefault(0):默认设置。通信模式下为 AgoraAudioProfileSpeechStandard(1),直播模式下为 AgoraAudioProfileMusicStandard(2) * AgoraAudioProfileSpeechStandard(1):指定 32 kHz 的采样率,语音编码,单声道,编码码率最大值为 18 kbps * AgoraAudioProfileMusicStandard(2):指定 48 kHz 的采样率,音乐编码,单声道,编码码率最大值为 48 kbps * AgoraAudioProfileMusicStandardStereo(3):指定 48 kHz 的采样率,音乐编码,双声道,编码码率最大值为 56 kbps * AgoraAudioProfileMusicHighQuality(4):指定 48 kHz 的采样率,音乐编码,单声道,编码码率最大值为 128 kbps * AgoraAudioProfileMusicHighQualityStereo(5):指定 48 kHz 的采样率,音乐编码,双声道,编码码率最大值为 192 kbps |
scenario | 设置音频的使用场景,如娱乐、教学和游戏直播等。声音的流畅度、噪声抑制、音质等会根据不同的场景做出优化: * AgoraAudioScenarioDefault(0):默认的音频应用场景 * AgoraAudioScenarioChatRoomEntertainment(1):娱乐应用,适用于需要频繁上下麦的场景 * AgoraAudioScenarioEducation(2):教育场景 * AgoraAudioScenarioGameStreaming(3):游戏直播以及高音质互动应用,音质优先,适用于聊天房唱歌表演的场景 * AgoraAudioScenarioShowRoom(4):秀场应用,连麦下音质仅次于 GameStreaming,拥有更好的专业外设支持 * AgoraAudioScenarioChatRoomGaming(5):游戏应用,适用于游戏开黑场景,如吃鸡 |
[agoraKit setAudioProfile: AgoraAudioProfileSpeechStandard scenario: AgoraAudioScenarioChatRoomGaming];
// 娱乐聊天室
注:该方法需要在 joinChannelByToken 之前调用。
系统音量分通话音量和媒体音量两种:
- 通话音量指的是进行语音、视频通话时的音量。通话音量有较好的回声消除。
- 媒体音量指的是播放音乐、视频或游戏的音效、背景音的音量。媒体音量有较好的声音表现力。
两者的差异在于媒体音量可以调整到 0,而通话音量不可以。
变声与混响
通过 setLocalVoiceChanger 可以选择以下预设的语音变声效果:
- 老男孩
- 小男孩
- 小女孩
- 猪八戒
- 空灵
- 绿巨人
// 设置变声效果为老男孩
[self.agoraKit setLocalVoiceChanger: AgoraAudioVoiceChangerOldMan];
// 关闭变声效果
[self.agoraKit setLocalVoiceChanger: AgoraAudioVoiceChangerOff];
通过 setLocalVoiceReverbPreset 可以选择以下预设的语音混响效果:
- 流行
- R&B
- 摇滚
- 嘻哈
- 演唱会
- KTV
- 录音棚
// 设置混响效果为流行
[self.agoraKit setLocalVoiceReverbPreset: AgoraAudioReverbPresetPopular];
// 关闭混响效果
[self.agoraKit setLocalVoiceReverbPreset: AgoraAudioReverbPresetOff];
如果预置效果无法满足你的需求,你也可以自行调整音调、均衡和混响设置。
setLocalVoiceEqualizationOfBandFrequency:withGain:
setLocalVoiceReverbOfType:withValue:
视频
开关
方法 | 功能 |
---|---|
enableVideo | 启用视频模块 |
disableVideo | 关闭视频模块 |
startPreview | 开启视频预览 |
stopPreview | 停止视频预览 |
enableLocalVideo | 开关本地视频采集 |
muteLocalVideoStream | 开关本地视频发送 |
muteRemoteVideoStream | 停止/恢复接收指定视频流 |
muteAllRemoteVideoStreams | 停止/恢复接收所有视频流 |
视频属性
初始化 AgoraRtcEngine 后,你可以在需要时调用 setVideoEncoderConfiguration 来设置视频属性,并在该方法中设置你想要的分辨率、帧率、码率、方向等参数。
- 如果想在加入频道前设置视频属性,在 enableVideo 之后、joinChannelByToken 前调用。
- 如果在加入频道后不需要重新设置视频编码属性,还可以在 enableVideo 前调用该方法,以加快首帧出图的时间。
- 加入频道后你也可以调用该方法,实时更新视频的编码属性。
// 配置一个 VideoEncoderConfiguration 实例
AgoraVideoEncoderConfiguration *config = [[AgoraVideoEncoderConfiguration alloc] initWithSize: AgoraVideoDimension640x360 frameRate: AgoraVideoFrameRateFps15 bitrate: AgoraVideoBitrateStandard orientationMode: AgoraVideoOutputOrientationModeAdaptative degradationPreference: AgoraDegradationMaintainQuality];
[agoraKit setVideoEncoderConfiguration: config];
参数:
size:分辨率
frameRate:帧率
bitrate:码率
orientationMode:视频方向,提供了 Adaptive、FixedLandscape 和 FixedPortrait 三种方向模式。
degradationPreference:低网速下的策略
参数均有预定义的值。
美颜
调用setBeautyEffectOptions 方法配置基础美颜功能。
该方法有 2 个参数:
enabled 代表是否开启美颜功能。
options 代表美颜选项,包含 lighteningContrastLevel(明暗对比度)、lightening(亮度)、smoothness(平滑度)、redness(红色度)四个参数,可用来实现美白、磨皮、红润等效果。
AgoraBeautyOptions *options = [[AgoraBeautyOptions alloc] init];
options.lighteningContrastLevel = AgoraLighteningContrastNormal;
options.rednessLevel = 0;
options.smoothnessLevel = 0;
options.lighteningContrastLevel = 0;
[self.agoraKit setBeautyEffectOptions:YES options:options];
注:
- 以上方法有返回值,返回值小于 0 表示方法调用失败。
- 美颜功能的开启会对低端机的性能造成影响,以至于无法达到预期的要求。对于低端机,视频编码设置为 360p 30 fps,720p 15 fps 或更高分辨率时,不建议开启美颜。
开启双流模式
// 开启视频双流模式。
[agoraKit enableDualStreamMode: YES];
// 将订阅的该路视频流设置为大流。
[agoraKit setRemoteVideoStream: uid type:AgoraVideoStreamTypeHigh];
// 将订阅的该路视频流设置为小流。
[agoraKit setRemoteVideoStream: uid type:AgoraVideoStreamTypeLow];
网络检测
// 配置一个 LastmileProbeConfig 实例。参数可参考 API 文档
AgoraLastmileProbeConfig *config = [[AgoraLastmileProbeConfig alloc] probeUplink: YES probeDownlink: YES expectedUplinkBitrate: 1000 expectedDownlinkBitrate: 1000];
// 加入频道前开始 Last-mile 网络探测
[agoraKit startLastmileProbeTest: config];
// 注册回调
// 开始 Last-mile 网络探测后,约 2 秒后会发生该回调
// quality 即为当前检测到的 quality 类型,可以根据此参数执行相关逻辑
- (void)rtcEngine:(AgoraRtcEngine * _Nonnull)engine lastmileQuality: (AgoraNetworkQuality)quality {
}
// 开始 Last-mile 网络探测后,约 30 秒后会发生该回调
// result 即为当前探测到的网络质量结果,可以根据此类执行相关逻辑
- (void)rtcEngine:(AgoraRtcEngine * _Nonnull)engine lastmileProbeResult: (AgoraLastmileProbeResult)result {
// (1)可以选择在回调内部结束测试。在测试结束前,Agora 建议不要调用其他 API 方法
[agoraKit stopLastmileProbeTest];
}
// (2)也可以选择在其他时候结束测试。在测试结束前,Agora 建议不要调用其他 API 方法
[agoraKit stopLastmileProbeTest];
日志
方法 | 功能 |
---|---|
setLogFile | 设置日志文件 |
setLogFileSize | 设置日志文件大小 |
setLogFilter | 设置日志输出等级 |