1、创建一个新项目,然后pod导入云信sdk:
终端命令顺便复习一下:
1、cd xxx/项目路径
2、touch Podfile 创建文件
3、Podfile open 打开文件
4、复制以下代码 添加需要导入的第三方库
platform :ios, '8.0' target 'xxx' do pod 'NIMSDK', '5.5.0',:inhibit_warnings => true end
5、pod install 下载第三方库到本地
**注:**inhibit_warnings参数:能够有效的抑制CocoaPods引入的第三方代码库产生的warning,但是有时候会产生意想不到的错误,请注意使用。
2、导入网易云云信的部分文件:
1、搜索“云信”,然后进入官网。千万别搜索“网易云”,虽然是看起来是一家公司,但是两个网站还不一样。我找不到这里的Demo在哪,找了半天没找到,着实把人坑了一把,这是惨痛的经验教训。
2、找到下载位置之后,直接拉到底部,选择ios源码下载:
3、打开源码项目,根据一下路径,将对应的文件导入自己的项目中:
3、Info.plist文件配置
sdk需要用到麦克风,所以:
Privacy - Microphone Usage Description
4、开始码代码:
1、在[AppDelegate.m]文件类中注册云信:
#import <NIMSDK/NIMSDK.h> - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. [AppDelegate configNIM]; return YES; } ///云信配置 +(void)configNIM{ //推荐在程序启动的时候初始化 NIMSDK NSString *appKey = @"xxx"; NIMSDKOption *option = [NIMSDKOption optionWithAppKey:appKey]; option.apnsCername = @"nil"; option.pkCername = @"nil"; [[NIMSDK sharedSDK] registerWithOption:option];
2、在进入视频页面之前,先登陆云信账号,再加入某个聊天室,最后再进入聊天室视频:
///跳转页面 -(void)jumpToVideoVC{ VideoVC *vc = [VideoVC new]; [self presentViewController:vc animated:YES completion:^{}]; } ///云信登录请求 - (void)getNimLoginWithShowHud:(BOOL)isShowHudErr response:(void(^)(NSError *error))response{ //云信登录 NSString *user_accid = @"xxx"; NSString *user_nimToken = @"xxx"; [[[NIMSDK sharedSDK] loginManager] login:user_accid token:user_nimToken completion:^(NSError *error) { !response?:response(error); if (error == nil){ NSString *userID = [NIMSDK sharedSDK].loginManager.currentAccount; if (userID) { NSString *nick = @"昵称"; NSString *headerUrl = @"https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLGrrnBlrnGDwlX6LOIhDv1UMicXKJ9jAv9TVicbVRmI6es3SkXU7bQrxziawS1LoR7CM54BNbrNTphg/132"; NSDictionary *dic = @{@(NIMUserInfoUpdateTagNick):nick,@(NIMUserInfoUpdateTagAvatar):headerUrl}; //更新昵称头像信息 [[NIMSDK sharedSDK].userManager updateMyUserInfo:dic completion:^(NSError *error) { !response?:response(error); }]; NSLog(@"云信登录成功"); } }else{ if (isShowHudErr == YES) { NSString *err = [NSString stringWithFormat:@"登录失败:%ld",(long)error.code]; NSLog(@"%@",err); } } }]; } /** 进入聊天室 @param roomId 聊天室id @param completion 返回结果 */ -(void)zm_enterChatroomWithRoomId:(NSString *_Nullable)roomId response:(nullable NIMChatroomEnterHandler)completion{ NIMUser *user = [[NIMSDK sharedSDK].userManager userInfo:[NIMSDK sharedSDK].loginManager.currentAccount]; NIMChatroomEnterRequest *request = [[NIMChatroomEnterRequest alloc] init]; request.roomId = roomId; request.roomNickname = user.userInfo.nickName; request.roomAvatar = user.userInfo.avatarUrl; [[[NIMSDK sharedSDK] chatroomManager] enterChatroom:request completion:^(NSError * _Nullable error, NIMChatroom * _Nullable chatroom, NIMChatroomMember * _Nullable me) { !completion?:completion(error,chatroom,me); if (error == nil){ }else{ NSLog(@"进入失败 enter room %@ failed %@ code:%zd",chatroom.roomId,error,error.code); } }]; }
3、进入聊天室后,要做好视频配置,加入视频会议,调用视频窗口,加入视频房间:
//thirds #import <NIMSDK/NIMSDK.h> #import <NIMAVChat/NIMAVChat.h> #import "NTESGLView.h" //设备宽高 #define kIphone_W [UIScreen mainScreen].bounds.size.width #define kIphone_H [UIScreen mainScreen].bounds.size.height
@interface VideoVC ()<NIMNetCallManagerDelegate> ///视频配置 @property(nonatomic,copy)NIMNetCallVideoCaptureParam *param; ///视频会议 @property(nonatomic,copy)NIMNetCallMeeting *meeting; ///视频窗口 @property(nonatomic,strong)NTESGLView *remoteGLView; ///当前摄像头名字 @property (nonatomic, strong) NSString * currentCamare; /// @property(nonatomic,copy)NSString *nimRoomName; ///按钮 @property(nonatomic,strong)UIButton *btn; @end
#pragma mark - initial - (void)viewDidLoad { [super viewDidLoad]; [self setBaseData]; [self setBaseUI]; } -(void)setBaseData{ self.nimRoomName = @"vchat_room_18"; self.currentCamare = @"vchat_room_18_user1"; //加入视频房间 [self joinNetCall:self with:self.nimRoomName]; } -(void)setBaseUI{ self.view.backgroundColor = [UIColor purpleColor]; [self remoteGLView]; [self btn]; }
#pragma mark - NIMNetCallManager 云信管理 ///加入房间 - (void)joinNetCall:(UIViewController<NIMNetCallManagerDelegate> *)delegate with:(NSString *)roomName{ self.meeting.name = roomName; [self joinNetCallWithRMeeting:self.meeting delegate:delegate]; } //加入 - (void)joinNetCallWithRMeeting:(NIMNetCallMeeting *)rMeeting delegate:(UIViewController<NIMNetCallManagerDelegate> *)vc{ NSLog(@"????===准备加入会议"); [[NIMAVChatSDK sharedSDK].netCallManager setMeetingRole:NO];//观众模式 [[NIMAVChatSDK sharedSDK].netCallManager selectVideoAdaptiveStrategy:NIMAVChatVideoAdaptiveStrategySmooth]; [[NIMAVChatSDK sharedSDK].netCallManager addDelegate:vc]; [[NIMAVChatSDK sharedSDK].netCallManager joinMeeting:rMeeting completion:^(NIMNetCallMeeting * _Nonnull meeting, NSError * _Nullable error) { if (!error) { NSLog(@"=========加入会议成功"); }else{ NSLog(@"%@",error.domain); } }]; } //离开房间 - (void)leaveRoom:(NSString *)roomName delegate:(UIViewController<NIMNetCallManagerDelegate> *)delegate{ self.meeting.name = roomName; [[NIMAVChatSDK sharedSDK].netCallManager leaveMeeting:self.meeting]; [[NIMAVChatSDK sharedSDK].netCallManager removeDelegate:delegate]; [_remoteGLView removeFromSuperview]; _remoteGLView = nil; self.meeting = nil; self.param = nil;
#pragma mark - NIMNetCallManagerDelegate //远程视频 YUV 数据就绪 //480*640 - (void)onRemoteYUVReady:(NSData *)yuvData width:(NSUInteger)width height:(NSUInteger)height from:(NSString *)user { if ([user isEqualToString:self.currentCamare]) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [_remoteGLView render:yuvData width:width height:height]; NSLog(@"\n?????\n%ld\n%@",yuvData.length,yuvData); }); } } ///用户加入了多人会议 - (void)onUserJoined:(NSString *)uid meeting:(NIMNetCallMeeting *)meeting{ } //音量回调 -(void)onMyVolumeUpdate:(UInt16)volume{ //刷新音量UI NSLog(@"%d",volume); } ///服务器录制信息回调 - (void)onNetCallRecordingInfo:(NIMNetCallRecordingInfo *)info{ } ///当前通话网络状态 - (void)onNetStatus:(NIMNetCallNetStatus)status user:(NSString *)user{ NSLog(@"网络状态:%ld and 用户 :%@",(long)status,user); if ([user isEqualToString:self.currentCamare]) { // [self changeSignal:status]; } }
#pragma mark - method - (UIViewContentMode)videochatRemoteVideoContentMode { NSInteger setting = [[[NSUserDefaults standardUserDefaults] objectForKey:@"videochat_remote_video_content_mode"] integerValue]; return (setting == 0) ? UIViewContentModeScaleAspectFill : UIViewContentModeScaleAspectFit; } -(void)btnAction:(UIButton *)sender{ __weak typeof(self) weakSelf = self; [self dismissViewControllerAnimated:YES completion:^{ [weakSelf leaveRoom:weakSelf.nimRoomName delegate:weakSelf]; }]; } #pragma mark - lazyload -(UIButton *)btn{ if (!_btn) { _btn = [UIButton buttonWithType:UIButtonTypeCustom]; _btn.frame = CGRectMake(100, 20, 100, 50); _btn.backgroundColor = [UIColor redColor]; [_btn setTitle:@"点击返回" forState:UIControlStateNormal]; [_btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:_btn]; } return _btn; } ///视频配置 - (void)fillVideoCaptureSetting:(NIMNetCallVideoCaptureParam *)param{ param.preferredVideoQuality = NIMNetCallVideoQuality480pLevel; param.videoCrop = NIMNetCallVideoCrop4x3; param.videoFrameRate = NIMNetCallVideoFrameRate20FPS; param.videoHandler = ^(CMSampleBufferRef _Nonnull sampleBuffer) { NSLog(@"%@",sampleBuffer); }; } - (NIMNetCallVideoCaptureParam *)param{ if (!_param) { _param = [[NIMNetCallVideoCaptureParam alloc]init]; [self fillVideoCaptureSetting:_param]; } return _param; } - (NIMNetCallMeeting *)meeting{ if (!_meeting) { _meeting = [[NIMNetCallMeeting alloc] init]; _meeting.type = NIMNetCallMediaTypeVideo; _meeting.actor = NO; _meeting.option.voiceDetect = NO; _meeting.option.videoCaptureParam = self.param; _meeting.option.pureVideo = YES; } return _meeting; } -(NTESGLView *)remoteGLView{ if (!_remoteGLView) { _remoteGLView = [[NTESGLView alloc] initWithFrame:CGRectMake(0, 100, kIphone_W, kIphone_W*0.75)]; _remoteGLView.backgroundColor = [UIColor greenColor]; [_remoteGLView setContentMode:[self videochatRemoteVideoContentMode]]; [_remoteGLView setBackgroundColor:[UIColor clearColor]]; [self.view addSubview:_remoteGLView]; } return _remoteGLView; }