====== iOS客户端集成 ====== ===== 前期准备 ===== 首先开发者需要在环信管理后台注册,参考[[im:000quickstart:10register|注册并创建应用]]。 **请注意: 因为demo中的推拉流使用的是临时地址,用户在集成时需要使用“服务器集成”中的方法设置自行申请的直播的推流拉流地址。** ===== iOS SDK介绍 ===== 环信即时通讯SDK和视频SDK共同构成直播解决方案,环信即时通讯负责聊天室创建、直播列表的获取、消息发送、点赞等功能;视频SDK负责直播中的视频的推流和拉流。 环信即时通讯云[[im:300iosclientintegration:20iossdkimport|iOS SDK 介绍及导入]]。 目前直播demo使用的视频SDK是UCloud直播SDK,[[https://github.com/umdk/UCDLive_iOS|文档及下载]]。 ===== iOS SDK导入 ===== === 使用CocoaPods导入SDK === 1. CocoaPods安装。 如果已经安装了CocoaPods,直接进入下一步即可。 sudo gem install cocoapods 2. 使用CocoaPods导入环信SDK。 pod 'HyphenateLite' === 手动导入 SDK === 1. 下载SDK:[[http://www.easemob.com/download/im|环信SDK]] 2. SDK中包含以下文件。 ./ChatDemo-UI3.0 ./ChatDemo-UI3.0.ipa ./EaseUI ./HyphenateFullSDK ./HyphenateSDK ./HyphenateVideoRecoder ./doc 3. 选择"./HyphenateSDK/HyphenateLite.framework",在开发者的项目中,向General > Embedded Binaries 中添加依赖库HyphenateLite.framework。 === 初始化SDK === 第 1 步:引入相关头文件。 #import 第 2 步:在工程的 AppDelegate 中的以下方法中,调用 SDK 对应方法。 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //AppKey:注册的AppKey,详细见下面注释。 //apnsCertName:推送证书名(不需要加后缀),详细见下面注释。 EMOptions *options = [EMOptions optionsWithAppkey:@"douser#istore"]; options.apnsCertName = @"istore_dev"; [[EMClient sharedClient] initializeSDKWithOptions:options]; return YES; } // APP进入后台 - (void)applicationDidEnterBackground:(UIApplication *)application { [[EMClient sharedClient] applicationDidEnterBackground:application]; } // APP将要从后台返回 - (void)applicationWillEnterForeground:(UIApplication *)application { [[EMClient sharedClient] applicationWillEnterForeground:application]; } 第 3 步:注册&登录。 //注册 EMError *error = [[EMClient sharedClient] registerWithUsername:@"8001" password:@"111111"]; if (error==nil) { NSLog(@"注册成功"); } //登录 EMError *error = [[EMClient sharedClient] loginWithUsername:@"8001" password:@"111111"]; if (!error) { NSLog(@"登录成功"); } ===== Demo源码 ===== 具体功能介绍,[[https://github.com/easemob/livestream_demo_ios.git|直播Demo源码]]。Demo中实现了创建直播、查看当前直播列表、直播、观看直播、消息发送、点赞等功能。 ^文件^功能^ |EaseLiveTVListViewController|直播列表页面| |EaseLiveViewController|观看直播页面| |EasePublishViewController|直播页面| |EaseCreateLiveViewController|创建直播页面| |EaseSearchDisplayController|直播搜索页面| |EaseHttpManager|直播相关接口| ===== 基础功能 ===== 1. 指定直播流id,开启预览。(当创建新的直播聊天室,会获得EaseLiveRoom,room.session.mobilepushstream就是推流地址,下面有具体的创建直播聊天室的接口说明。) //Ucloud 视频推流 /*! @method configureCameraWithOutputUrl:filter:messageCallBack:deviceBlock:cameraData: @abstract server初始化(不会自动开始要在底层配置完成之后调用cameraStart) @param outPutUrl 推流地址 @param filters 滤镜组 @param block 推流状态回调 @param deviceBlock 相机回调(定制相机参数) @param cameraData 视频数据 @discussion 推流从此进入 */ - (void)configureCameraWithOutputUrl:(NSString *)outPutUrl filter:(NSArray *)filters messageCallBack:(CameraMessage)block deviceBlock:(CameraDevice)deviceBlock cameraData:(CameraData)cameraData; //示例代码 NSString *path = _room.session.mobilepushstream NSArray *filters = [self.filterManager filters]; [[CameraServer server] configureCameraWithOutputUrl:path filter:filters messageCallBack:^(UCloudCameraCode code, NSInteger arg1, NSInteger arg2, id data){ if (code == UCloudCamera_BUFFER_OVERFLOW) { //推流带宽 } else if (code == UCloudCamera_SecretkeyNil) { //密钥为空 } else if (code == UCloudCamera_PreviewOK) { //预览视图准备好 } else if (code == UCloudCamera_PublishOk) { //底层推流配置完毕 } else if (code == UCloudCamera_StartPublish) { //开始直播 } else if (code == UCloudCamera_Permission) { //相机授权 } else if (code == UCloudCamera_Micphone) { //麦克风授权 } } deviceBlock:^(AVCaptureDevice *dev) { //相机回掉(定制相机参数) } cameraData:^CMSampleBufferRef(CMSampleBufferRef buffer) { //若果不需要裸流,不建议在这里执行操作,讲增加额外的功耗 return nil; }]; 2. 通过指定流id观看直播。(获取当前直播聊天室列表时,会获得EaseLiveRoom,room.session.mobilepullstream就是拉流地址,下面有具体的获取直播聊天室列表的接口说明。) //Ucloud 视频拉流 //示例代码,PlayerManager.h - (void)viewDidLoad { [super viewDidLoad]; PlayerManager *playerManager = [[PlayerManager alloc] init]; playerManager.retryConnectNumber = 0; playerManager.view = self.view; playerManager.viewContorller = self; float height = self.view.frame.size.height; [playerManager setPortraitViewHeight:height] [playerManager buildMediaPlayer:@"视频拉流地址"]; } 3. 加入聊天室。 //EaseHttpManager.h /* * 用户加入直播聊天室 * * @param aRoomId 直播聊天室ID * @param aChatroomId 聊天室ID * @param aIsCount 是否计数 * @param aCompletion 完成的回调block */ - (void)joinLiveRoomWithRoomId:(NSString*)aRoomId chatroomId:(NSString*)aChatroomId isCount:(BOOL)aIsCount completion:(void (^)(BOOL success))aCompletion //示例代码 [[EaseHttpManager sharedInstance] joinLiveRoomWithRoomId:@"直播室ID" chatroomId:@"聊天室ID" isCount:YES completion:^(BOOL success) { }]; 4. 离开聊天室。 //EaseHttpManager.h /* * 用户离开直播聊天室 * * @param aRoomId 直播聊天室ID * @param aChatroomId 聊天室ID * @param aIsCount 是否计数 * @param aCompletion 完成的回调block */ - (void)leaveLiveRoomWithRoomId:(NSString*)aRoomId chatroomId:(NSString*)aChatroomId isCount:(BOOL)aIsCount completion:(void (^)(BOOL success))aCompletion; //示例代码 [[EaseHttpManager sharedInstance] leaveLiveRoomWithRoomId:@"直播室ID" chatroomId:@"聊天室ID" isCount:YES completion:^(BOOL success) { }]; ===== 发送消息 ===== 1. 发送消息。 /*! * \~chinese * 发送消息 * * @param aMessage 消息 * @param aProgressBlock 附件上传进度回调block * @param aCompletionBlock 发送完成回调block * * \~english * Send a message * * * @param aMessage Message instance * @param aProgressBlock The block of attachment upload progress * @param aCompletionBlock The block of send complete */ - (void)sendMessage:(EMMessage *)aMessage progress:(void (^)(int progress))aProgressBlock completion:(void (^)(EMMessage *message, EMError *error))aCompletionBlock; //示例代码 EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"发送内容"]; NSString *from = [[EMClient sharedClient] currentUsername]; EMMessage *message = [[EMMessage alloc] initWithConversationID:aChatroomId from:from to:aChatroomId body:body ext:nil]; message.chatType = EMChatTypeChatRoom; [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *message, EMError *error) { if (!error) { //消息发送成功 } }]; 请参考[[im:300iosclientintegration:40emmsg|消息收发]] 您可以使用透传消息来实现礼物,撒花等聊天室常见功能,比如cmd里面action: flower, UI上显示撒花效果,如果action: plane 就显示成送飞机做礼物 2. 设置消息监听。 //示例代码 [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil]; - (void)messagesDidReceive:(NSArray *)aMessages { //收到普通消息 } - (void)cmdMessagesDidReceive:(NSArray *)aCmdMessages { //收到cmd消息 } ===== 聊天室管理 ===== 1. 创建直播聊天室,拥有主播权限的用户可以创建新的直播聊天室,可以包括封面、题目、描述等信息。创建成功后会返回推流地址和聊天室ID。 //EaseHttpManager.h /* * 创建直播聊天室 * * @param aRoom 直播聊天室 * @param aCompletion 完成的回调block */ - (void)createLiveRoomWithRoom:(EaseLiveRoom*)aRoom completion:(void (^)(EaseLiveRoom *room, BOOL success))aCompletion; //示例代码 EaseLiveRoom *liveRoom = [[EaseLiveRoom alloc] init]; liveRoom.title = @"直播聊天室title"; liveRoom.desc = @"直播聊天室描述"; liveRoom.session.anchor = [EMClient sharedClient].currentUsername; liveRoom.coverPictureUrl = @"封面图片Url"; [[EaseHttpManager sharedInstance] createLiveRoomWithRoom:liveRoom completion:^(EaseLiveRoom *room, BOOL success) { }]; 2. 获取直播聊天室,这里指的是获取正在直播的聊天室列表。(后台状态是正在直播的直播聊天室,只要后台的状态是正在直播,就会显示在这个列表里面,无论是否有主播在推流。) //EaseHttpManager.h /* * 获取正在直播聊天室列表 * * @param aCursor 游标 * @param aLimit 预期获取的记录数 * @param aCompletion 完成的回调block */ - (void)fetchLiveRoomsOngoingWithCursor:(NSString*)aCursor limit:(NSInteger)aLimit completion:(void (^)(EMCursorResult *result, BOOL success))aCompletion; //示例代码 [[EaseHttpManager sharedInstance] fetchLiveRoomsOngoingWithCursor:nil limit:20 completion:^(EMCursorResult *result, BOOL success) { }]; 3. 获取直播聊天室详情,封面图片url、直播聊天室题目、描述等信息。 //EaseHttpManager.h /* * 获取直播聊天室详情 * * @param aRoomId 直播聊天室ID * @param aCompletion 完成的回调block */ - (void)getLiveRoomWithRoomId:(NSString*)aRoomId completion:(void (^)(EaseLiveRoom *room, BOOL success))aCompletion; //示例代码 [[EaseHttpManager sharedInstance] getLiveRoomWithRoomId:@"直播聊天室ID" completion:^(EaseLiveRoom *room, BOOL success) { }]; 4. 获取直播聊天室状态,目前直播聊天室的状态有五种。 typedef enum { EaseLiveSessionUnknown,//未知状态 EaseLiveSessionNotStart,//直播未开始 EaseLiveSessionOngoing,//正在直播中 EaseLiveSessionCompleted,//直播已经完成 EaseLiveSessionClosed//直播已经关闭 } EaseLiveSessionStatus; //EaseHttpManager.h /* * 获取直播聊天室状态 * * @param aRoomId 直播聊天室ID * @param aCompletion 完成的回调block */ - (void)getLiveRoomStatusWithRoomId:(NSString*)aRoomId completion:(void (^)(EaseLiveSessionStatus status, BOOL success))aCompletion; //示例代码 [[EaseHttpManager sharedInstance] getLiveRoomStatusWithRoomId:@"直播聊天室ID" completion:^(EaseLiveSessionStatus status, BOOL success) { ]; 5. 修改直播聊天室状态,当直播结束的时候,主动修改直播聊天室的状态,避免在直播列表里面显示。 //EaseHttpManager.h /* * 修改直播聊天室状态 * * @param aRoomId 直播聊天室ID * @param aStatus 直播聊天室状态 * @param aCompletion 完成的回调block */ - (void)modifyLiveRoomStatusWithRoomId:(NSString*)aRoomId status:(EaseLiveSessionStatus)aStatus completion:(void (^)(BOOL success))aCompletion; //示例代码 [[EaseHttpManager sharedInstance] modifyLiveRoomStatusWithRoomId:@"直播聊天室ID" status:EaseLiveSessionCompleted completion:^(BOOL success) { }]; 6. 创建新的直播场次,当一个直播结束后,用户可以创建一个新的直播场次,可以在原有直播聊天室开始新的直播。 //EaseHttpManager.h /* * 创建新的直播场次 * * @param aRoom 直播聊天室 * @param aCompletion 完成的回调block */ - (void)createLiveSessionWithRoom:(EaseLiveRoom*)aRoom completion:(void (^)(EaseLiveRoom *room, BOOL success))aCompletion; //示例代码 //_liveRoom是已经获取的直播聊天室 [[EaseHttpManager sharedInstance] createLiveSessionWithRoom:_liveRoom completion:^(EaseLiveRoom *room, BOOL success) { }]; ===== 观众管理 ===== 1. 禁言和解除禁言,需要直播的群主和管理员有权限。 // IEMChatroomManager /*! * 将一组成员禁言,需要Owner / Admin权限 * * 同步方法,会阻塞当前线程 * * @param aMuteMembers 要禁言的成员列表 * @param aMuteMilliseconds 禁言时长 * @param aChatroomId 聊天室ID * @param pError 错误信息 * * @result 聊天室实例 */ - (EMChatroom *)muteMembers:(NSArray *)aMuteMembers muteMilliseconds:(NSInteger)aMuteMilliseconds fromChatroom:(NSString *)aChatroomId error:(EMError **)pError; //示例代码 EMError *error = nil; [[EMClient sharedClient].roomManager muteMembers:@[@"用户ID"] muteMilliseconds:-1 fromChatroom:@"聊天室ID" error:&error]; /*! * 解除禁言,需要Owner / Admin权限 * * 同步方法,会阻塞当前线程 * * @param aMuteMembers 被解除的列表 * @param aChatroomId 聊天室ID * @param pError 错误信息 * * @result 聊天室实例 */ - (EMChatroom *)unmuteMembers:(NSArray *)aMembers fromChatroom:(NSString *)aChatroomId error:(EMError **)pError; //示例代码 EMError *error = nil; [[EMClient sharedClient].roomManager unmuteMembers:@[@"用户ID"] fromChatroom:@"聊天室ID" error:&error]; 2. 加入黑名单,从黑名单移除,需要直播的群主有权限。 /*! * 加人到聊天室黑名单, 需要owner权限 * * @param aMembers 要加入黑名单的用户 * @param aChatroomId 聊天室ID * @param aCompletionBlock 完成的回调 */ - (void)blockMembers:(NSArray *)aMembers fromChatroom:(NSString *)aChatroomId completion:(void (^)(EMChatroom *aChatroom, EMError *aError))aCompletionBlock; //示例代码 [[EMClient sharedClient].roomManager blockMembers:@[@"用户ID"] fromChatroom:@"聊天室ID" completion:^(EMChatroom *aChatroom, EMError *aError) { }]; /*! * 从聊天室黑名单中减人, 需要owner权限 * * @param aMembers 要从黑名单中移除的用户名列表 * @param aChatroomId 聊天室ID * @param aCompletionBlock 完成的回调 */ - (void)unblockMembers:(NSArray *)aMembers fromChatroom:(NSString *)aChatroomId completion:(void (^)(EMChatroom *aChatroom, EMError *aError))aCompletionBlock; //示例代码 [[EMClient sharedClient].roomManager unblockMembers:@[@"用户ID"] fromChatroom:@"聊天室ID" completion:^(EMChatroom *aChatroom, EMError *aError) { }]; 3. 聊天室踢人,需要直播的群主和管理员的权限。 /*! * 将成员移出聊天室, 需要owner/admin权限 * * @param aMembers 要移出的用户列表 * @param aChatroomId 聊天室ID * @param aCompletionBlock 完成的回调 */ - (void)removeMembers:(NSArray *)aMembers fromChatroom:(NSString *)aChatroomId completion:(void (^)(EMChatroom *aChatroom, EMError *aError))aCompletionBlock; //示例代码 [[EMClient sharedClient].roomManager removeMembers:@[@"用户ID"] fromChatroom:@"聊天室ID" completion:^(EMChatroom *aChatroom, EMError *aError) { }]; 4. 设置管理员,移除管理员,需要直播群主的权限。 /*! * 添加聊天室管理员,需要Owner权限 * * @param aAdmin 要添加的群组管理员 * @param aChatroomId 聊天室ID * @param aCompletionBlock 完成的回调 */ - (void)addAdmin:(NSString *)aAdmin toChatroom:(NSString *)aChatroomId completion:(void (^)(EMChatroom *aChatroomp, EMError *aError))aCompletionBlock; //示例代码 [[EMClient sharedClient].roomManager addAdmin:@"用户ID" toChatroom:@"聊天室ID" completion:^(EMChatroom *aChatroomp, EMError *aError) { }]; /*! * 移除聊天室管理员,需要Owner权限 * * @param aAdmin 要添加的群组管理员 * @param aChatroomId 聊天室ID * @param aCompletionBlock 完成的回调 * */ - (void)removeAdmin:(NSString *)aAdmin fromChatroom:(NSString *)aChatroomId completion:(void (^)(EMChatroom *aChatroom, EMError *aError))aCompletionBlock; //示例代码 [[EMClient sharedClient].roomManager removeAdmin:@"用户ID" fromChatroom:@"聊天室ID" completion:^(EMChatroom *aChatroom, EMError *aError) { }]; 5. 获取聊天室成员列表。 /*! * 获取聊天室成员列表 * * @param aChatroomId 聊天室ID * @param aCursor 游标,首次调用传空 * @param aPageSize 获取多少条 * @param pError 错误信息 * * @return 列表和游标 */ - (EMCursorResult *)getChatroomMemberListFromServerWithId:(NSString *)aChatroomId cursor:(NSString *)aCursor pageSize:(NSInteger)aPageSize error:(EMError **)pError; //示例代码 [[EMClient sharedClient].roomManager getChatroomMemberListFromServerWithId:@"聊天室ID" cursor:nil pageSize:10 completion:^(EMCursorResult *aResult, EMError *aError) { }]; 6. 观众的加入聊天室和离开聊天室。 //注册聊天室的回调 [[EMClient sharedClient].roomManager addDelegate:self delegateQueue:nil]; - (void)userDidJoinChatroom:(EMChatroom *)aChatroom user:(NSString *)aUsername { //观众加入聊天室 } - (void)userDidLeaveChatroom:(EMChatroom *)aChatroom user:(NSString *)aUsername { //观众离开聊天室 } ===== 主播管理 ===== 获取主播关联直播聊天室列表,当用户创建新的直播聊天室或者后台操作,都可以关联之前创建的直播聊天室,用户可以使用之前创建的直播聊天室,继续直播或者创建新的直播场次。 //EaseHttpManager.h /* * 获取一个主播关联的直播聊天室列表 * * @param aUsername 直播环信ID * @param aPage 获取第几页 * @param aPageSize 获取多少条 * @param aCompletion 完成的回调block */ - (void)getLiveRoomListWithUsername:(NSString*)aUsername page:(NSInteger)aPage pagesize:(NSInteger)aPageSize completion:(void (^)(NSArray *roomList, BOOL success))aCompletion; //示例代码 [[EaseHttpManager sharedInstance] getLiveRoomListWithUsername:[EMClient sharedClient].currentUsername page:0 pagesize:20 completion:^(NSArray *roomList, BOOL success) { }]; ---- 上一页:[[im:live:android-integration|Android客户端集成]] 下一页:[[im:live:console|直播管理后台使用]]