// // TRTCRtcImpl.m // xplan-ios // // Created by zu on 2021/12/6. // #import "TRTCRtcImpl.h" #import "XPConstant.h" #import "XPMacro.h" #import @interface TRTCRtcImpl() @property (strong, nonatomic) TRTCCloud *engine; ///背景音乐管理 @property (nonatomic, strong) TXAudioEffectManager *musicManager; ///音乐播放完成 @property (nonatomic,copy) void(^MusicCompletion)(NSString *filePath); ///音乐的id @property (nonatomic,assign) int musicId; @end @implementation TRTCRtcImpl - (instancetype)initWithDelegate:(id)delegate { self = [super initWithDelegate:delegate]; if (self) { _engine = [TRTCCloud sharedInstance]; [_engine enableAudioVolumeEvaluation:900]; [TRTCCloud setConsoleEnabled:NO]; _engine.delegate = self; } return self; } #pragma mark - RtcInterface impl - (BOOL)joinChannel:(NSString *)channelId sign:(nonnull NSString *)sign completion:(void (^)(void))completion { [self.engine enableAudioVolumeEvaluation:900]; TRTCParams *params = [[TRTCParams alloc] init]; UInt32 appId; sscanf([KeyWithType(KeyType_TRTC) UTF8String], "%u", &appId); params.sdkAppId = appId; UInt32 roomId; sscanf([channelId UTF8String], "%u", &roomId); params.roomId = roomId; params.userId = [[AccountInfoStorage instance] getUid]; params.userSig = sign; params.role = TRTCRoleAudience; [self.engine enterRoom:params appScene:TRTCAppSceneLIVE]; if (completion) { completion(); } return YES; } ///发起跨房通话 - (void)connectOtherRoom:(NSString *)roomUid userId:(NSString *)uid { NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc] init]; if (roomUid.integerValue > INT_MAX) { [jsonDict setObject:@(uid.integerValue) forKey:@"roomId"]; } else { [jsonDict setObject:@([roomUid intValue]) forKey:@"roomId"]; } [jsonDict setObject:uid forKey:@"userId"]; NSData* jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict options:NSJSONWritingPrettyPrinted error:nil]; NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; [self.engine connectOtherRoom:jsonString]; } ///退出跨房通话 - (void)disconnectOtherRoom { [self.engine disconnectOtherRoom]; } ///发起跨房通话回调 - (void)onConnectOtherRoom:(NSString *)userId errCode:(TXLiteAVError)errCode errMsg:(NSString *)errMsg { if (errCode == ERR_NULL) { } } ///退出跨房通话回调 - (void)onDisconnectOtherRoom:(TXLiteAVError)errCode errMsg:(NSString *)errMsg { } - (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available { NSLog(@"成功userid:%@", userId); if (available) { } } - (BOOL)muteRemote:(BOOL)mute { [self.engine muteAllRemoteAudio:mute]; return YES; } - (BOOL)muteRemote:(BOOL)mute userId:(NSString *)userId { [self.engine muteRemoteAudio:userId mute:mute]; return YES; } - (void)broadcast:(BOOL)on { [self.engine switchRole:on ? TRTCRoleAnchor : TRTCRoleAudience]; if (on) { NSString *jsonString = @"{\"api\":\"setAudioQualityEx\",\"params\":{\"sampleRate\":48000,\"channel\":2,\"bitrate\":192,\"encodeMode\":1,\"systemVolumeType\":1}}"; [self.engine callExperimentalAPI:jsonString]; NSString *aecString = @"{\"api\":\"enableAudioAEC\",\"params\":{\"enable\":1,\"level\":100}}"; [self.engine callExperimentalAPI:aecString]; [self.engine startLocalAudio:TRTCAudioQualityMusic]; } else { [self.engine stopLocalAudio]; } } - (BOOL)muteLocal:(BOOL)mute { [self.engine muteLocalAudio:mute]; return YES; } - (void)exitChannel:(void (^)(void))completion { /** * 1.2 离开房间 * * 调用 exitRoom() 接口会执行退出房间的相关逻辑,例如释放音视频设备资源和编解码器资源等。 * 待资源释放完毕,SDK 会通过 TRTCCloudDelegate 中的 onExitRoom() 回调通知到您。 * * 如果您要再次调用 enterRoom() 或者切换到其他的音视频 SDK,请等待 onExitRoom() 回调到来之后再执行相关操作。 * 否则可能会遇到摄像头或麦克风(例如 iOS 里的 AudioSession)被占用等各种异常问题。 */ [self.engine exitRoom]; if (completion) { completion(); } } - (void)destory { [TRTCCloud destroySharedIntance]; } /// 播放背景音乐 /// @param filePath 音频文件的地址 /// @param musicId TRTC自己要的 - (BOOL)playBackMusic:(NSString *)filePath musicId:(int)musicId completion:(void (^)(NSString *))completion{ if (filePath) { self.MusicCompletion = completion; [self changePlayState:BackMusicPlayState_Stop];//切换歌曲need stop self.musicId = musicId; if (self.musicManager == nil) { self.musicManager = [self.engine getAudioEffectManager]; } TXAudioMusicParam *param = [[TXAudioMusicParam alloc] init]; param.ID = musicId; param.path = filePath; @kWeakify(self); [self.musicManager startPlayMusic:param onStart:^(NSInteger errCode) { } onProgress:^(NSInteger progressMs, NSInteger durationMs) { } onComplete:^(NSInteger errCode) { @kStrongify(self); self.MusicCompletion(filePath); ///这个用在最小化的时候 因为最小化没办法知道当前歌曲是否播放完毕了 目前没有想到其他的好的版本就用通知吧 [[NSNotificationCenter defaultCenter] postNotificationName:kRoomBackMusicPlayMusicFinishKey object:filePath]; }]; return YES; } else { return NO; } } /// 改变播放器的状态 /// @param state 播放状态 - (BOOL)changePlayState:(BackMusicPlayState)state { BOOL isPlaying = NO; switch (state) { case BackMusicPlayState_Stop: { [self.musicManager stopPlayMusic:self.musicId]; isPlaying = NO; } break; case BackMusicPlayState_Pause: { [self.musicManager pausePlayMusic:self.musicId]; isPlaying = NO; } break; case BackMusicPlayState_Resume: { [self.musicManager resumePlayMusic:self.musicId]; isPlaying = YES; } default: break; } return isPlaying; } - (void)updateUserSound:(int)soundVol { [self.engine setAudioCaptureVolume:soundVol]; } - (void)updateMusicSound:(int)soundVol { [self.musicManager setMusicPublishVolume:self.musicId volume:soundVol * 1.5]; [self.musicManager setMusicPlayoutVolume:self.musicId volume:soundVol * 1.5]; } #pragma mark - TRTCCloudDelegate - (void)onUserVoiceVolume:(NSArray *)userVolumes totalVolume:(NSInteger)totalVolume { NSMutableArray *uids = [NSMutableArray array]; for (TRTCVolumeInfo *userInfo in userVolumes) { NSString *uid = userInfo.userId; if (userInfo.volume > 2){ if (uid.integerValue == 0) { [uids addObject:[[AccountInfoStorage instance] getUid]]; }else { [uids addObject:uid]; } } } [self.delegate usersSpeaking:uids]; } @end