目录

iOS客户端集成

前期准备

首先开发者需要在环信管理后台注册,参考注册并创建应用

请注意: 因为demo中的推拉流使用的是临时地址,用户在集成时需要使用“服务器集成”中的方法设置自行申请的直播的推流拉流地址。

iOS SDK介绍

环信即时通讯SDK和视频SDK共同构成直播解决方案,环信即时通讯负责聊天室创建、直播列表的获取、消息发送、点赞等功能;视频SDK负责直播中的视频的推流和拉流。

环信即时通讯云iOS SDK 介绍及导入

目前直播demo使用的视频SDK是UCloud直播SDK,文档及下载

iOS SDK导入

使用CocoaPods导入SDK

1. CocoaPods安装。

如果已经安装了CocoaPods,直接进入下一步即可。

sudo gem install cocoapods

2. 使用CocoaPods导入环信SDK。

pod 'HyphenateLite'

手动导入 SDK

1. 下载SDK:环信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 <HyphenateLite/HyphenateLite.h>

第 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源码

具体功能介绍,直播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) {
	//消息发送成功
	}
}]; 

请参考消息收发

您可以使用透传消息来实现礼物,撒花等聊天室常见功能,比如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         要禁言的成员列表<NSString>
 *  @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     被解除的列表<NSString>
 *  @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) {
                                                   }];