iOS SDK集成

本文介绍语聊房iOS集成的代码示例及集成说明。

功能时序图

image.png

主播创建房间

/* 实现AliRtcEngineDelegate 监听回调 */
_engine = [AliRtcEngine sharedInstance:self extras:extras];

//设置频道模式
[self.engine setChannelProfile:AliRtcInteractivelive];
//设置用户角色
[self.engine setClientRole:AliRtcClientRoleInteractive];
[self.engine setAudioProfile:AliRtcEngineHighQualityMode audio_scene:AliRtcSceneMusicMode];

//拉流设置
[self.engine setDefaultSubscribeAllRemoteAudioStreams:YES];
[self.engine subscribeAllRemoteAudioStreams:YES];
[self.engine publishLocalAudioStream:YES];
[self.engine setAudioOnlyMode:YES];

/* 是否听筒播放 */
[self.engine enableSpeakerphone:ctrl.useSpeaker];

NSMutableDictionary *raw_token = [[NSMutableDictionary alloc] init];
[raw_token setValue:info.appId forKey:@"appid"];
[raw_token setValue:info.channelId forKey:@"channelid"];
[raw_token setValue:info.userId forKey:@"userid"];
[raw_token setValue:info.nonce forKey:@"nonce"];
[raw_token setValue:@(info.timestamp) forKey:@"timestamp"];
[raw_token setValue:info.gslb forKey:@"gslb"];
[raw_token setValue:info.token forKey:@"token"];
NSData *token_data = [NSJSONSerialization dataWithJSONObject:raw_token options:NSJSONWritingPrettyPrinted error:nil];
NSString *token_str = [token_data base64EncodedStringWithOptions:0];
                
[self.engine joinChannel:token_str channelId:nil userId:nil name:nil onResultWithUserId:^(NSInteger errCode, NSString * _Nonnull channel, NSString * _Nonnull userId, NSInteger elapsed) {
    NSString *sting = [NSString stringWithFormat:@"joinRst: %d", (int)errCode];
    [weakSelf log:sting];
    if(errCode != 0 && ![weakSelf.engine isInCall]){
        weakSelf.callState = YES; // restore gui
    }else{
        weakSelf.callState = NO; //入会成功
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf addTableView]; //渲染远端视图
        });
    }
}];

观众加入房间

和主播创建房间调用接口相同,根据是否上麦,设置角色信息,以观众为示例:

/* 实现AliRtcEngineDelegate 监听回调 */
_engine = [AliRtcEngine sharedInstance:self extras:extras];

//设置频道模式
[self.engine setChannelProfile:AliRtcClientRoleInteractive];
//设置用户角色
[self.engine setClientRole:AliRtcClientRoleInteractive];
[self.engine setAudioProfile:AliRtcEngineHighQualityMode audio_scene:AliRtcSceneMusicMode];

//拉流设置
[self.engine setDefaultSubscribeAllRemoteAudioStreams:YES];
[self.engine subscribeAllRemoteAudioStreams:YES];
[self.engine publishLocalAudioStream:YES];
[self.engine setAudioOnlyMode:YES];

/* 是否听筒播放 */
[self.engine enableSpeakerphone:ctrl.useSpeaker];

NSMutableDictionary *raw_token = [[NSMutableDictionary alloc] init];
[raw_token setValue:info.appId forKey:@"appid"];
[raw_token setValue:info.channelId forKey:@"channelid"];
[raw_token setValue:info.userId forKey:@"userid"];
[raw_token setValue:info.nonce forKey:@"nonce"];
[raw_token setValue:@(info.timestamp) forKey:@"timestamp"];
[raw_token setValue:info.gslb forKey:@"gslb"];
[raw_token setValue:info.token forKey:@"token"];
NSData *token_data = [NSJSONSerialization dataWithJSONObject:raw_token options:NSJSONWritingPrettyPrinted error:nil];
NSString *token_str = [token_data base64EncodedStringWithOptions:0];
                
[self.engine joinChannel:token_str channelId:nil userId:nil name:nil onResultWithUserId:^(NSInteger errCode, NSString * _Nonnull channel, NSString * _Nonnull userId, NSInteger elapsed) {
    NSString *sting = [NSString stringWithFormat:@"joinRst: %d", (int)errCode];
    [weakSelf log:sting];
    if(errCode != 0 && ![weakSelf.engine isInCall]){
        weakSelf.callState = YES; // restore gui
    }else{
        weakSelf.callState = NO; //入会成功
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf addTableView]; //渲染远端视图
        });
    }
}];

观众切换角色

/* 之前已经入会,切换为主播角色 */
[self.engine setClientRole:AliRtcInteractivelive];

设置音量、变声、混响

/* 调整本人采集音量 */
[self.engine setRecordingVolume:volume];
/* 调整远端特定user的音量 */
[self.engine setRemoteAudioVolume:uid volume:volume];
/* 调整所有声音的播放音量 */
[self.engine setPlayoutVolume:volume];
/* 设置变声器 */
[self.engine setAudioEffectVoiceChangerMode:(AliRtcAudioEffectVoiceChangerMode)mode];
/* 设置混响 */
[self.engine setAudioEffectReverbParamType:paramType value:value];

播放背景音乐

pcm数据输入

创建音乐输入

AliRtcExternalAudioStreamConfig *config = [AliRtcExternalAudioStreamConfig new];
config.channels = _pcmLocalChannels;
config.sampleRate = _pcmLocalSampleRate;
/* 如果需要外放出来声音,设置外放音量 */
config.publishVolume = 60;
config.playoutVolume = 100;
/* 该stream id需要存下来,用于添加pcm数据和删除流 */
_externalPlayoutStreamId = [self.engine addExternalAudioStream:config];

输入pcm

/* 送入pcm数据 */ 
AliRtcAudioFrame *sample = [AliRtcAudioFrame new];
sample.dataPtr = _pcmLocalData;
sample.samplesPerSec = _pcmLocalSampleRate;
sample.bytesPerSample = sizeof(int16_t);
sample.numOfChannels = _pcmLocalChannels;
sample.numOfSamples = numOfSamples;
int rc = [self.engine pushExternalAudioStream:_externalPlayoutStreamId rawData:sample];

文件输入

AliRtcAudioAccompanyConfig *config = [AliRtcAudioAccompanyConfig new];
config.onlyLocalPlay = YES;
config.replaceMic = NO;
config.loopCycles = 1;
int code = [strongSelf.engine startAudioAccompanyWithFile:fileName config:config];