然后说一下这个,iOS音视频接入 – TRTC多人音视频通话

前一篇我们使用腾讯封装的TRTCCalling接入了1v1的音视频通话,今天还是使用此模块进行实现多人音视频通话及其常用TRTCSDK的API。

多人语音通话

使用API发起通话

在TRTCCalling中可以看到1v1语音通话和多人语音通话有不同的API使用,分别为

/// 发起1v1通话接口
/// @param userID 被邀请方ID
/// @param type 通话类型:视频/语音
- (void)call:(NSString *)userID
        type:(CallType)type
NS_SWIFT_NAME(call(userID:type:));

/// 发起多人通话
/// @param userIDs 被邀请方ID列表
/// @param type 通话类型:视频/语音
/// @param groupID 群组ID,可选参数
- (void)groupCall:(NSArray *)userIDs
             type:(CallType)type
          groupID:(NSString * _Nullable)groupID
NS_SWIFT_NAME(groupCall(userIDs:type:groupID:));

从API中可以看出对人通话需要传入被邀请方的ID是一个数组类型,数组内部存放被邀请人的ID,groupID-群组ID为一个可选参数,此参数为发起邀请所在的群,如果不是在一个IM群里发起的,groupID可以传一个空字符串。

当调用发起多人语音邀请后,先判断了当前是否在通话中,如果没有在通话中,则记录当前通话的邀请者、通话类型、群组ID、设置当前为通话中后组装进房参数。在自己进入房间后,在更新新添加的邀请人,并发起通话邀请(此内部实现逻辑可根据自己需求实现)。

- (void)call:(NSArray *)userIDs groupID:(NSString *)groupID type:(CallType)type {
    if (!self.isOnCalling) {
        self.curLastModel.inviter = [TRTCCallingUtils loginUser];
        self.curLastModel.action = CallAction_Call;
        self.curLastModel.calltype = type;
        self.curRoomID = [TRTCCallingUtils generateRoomID];
        self.curGroupID = groupID;
        self.curType = type;
        self.isOnCalling = YES;
        [self enterRoom];
    }
    // 不在当前邀请列表,新增加的邀请
    NSMutableArray *newInviteList = [NSMutableArray array];
    for (NSString *userID in userIDs) {
        if (![self.curInvitingList containsObject:userID]) {
            [newInviteList addObject:userID];
        }
    }
    [self.curInvitingList addObjectsFromArray:newInviteList];
    
    // 更新已经回复的列表,移除正在邀请的人
    NSMutableArray *rmRespList = [NSMutableArray array];
    for (NSString *userID in self.curRespList) {
        if ([self.curInvitingList containsObject:userID]) {
            [rmRespList addObject:userID];
        }
    }
    [self.curRespList removeObjectsInArray:rmRespList];
    
    //通话邀请
    if (self.curGroupID.length > 0 && newInviteList.count > 0) {
        self.curCallID = [self invite:self.curGroupID action:CallAction_Call model:nil];
    } else {
        for (NSString *userID in newInviteList) {
            self.curCallID = [self invite:userID action:CallAction_Call model:nil];
        }
    }
}

最后跟代码发现发起语音通话的信令是通过TXIMSDK进行。

通话邀请回调

当我们被邀请时SDK会回调以下方法,在此方法中我们可自定义处理此邀请的交互,比如presentVC、pushVC以及默认接听或判断为某个用户默认挂断等。

/// 被邀请通话回调 | invitee callback
/// - Parameter userIds: 邀请列表 (invited list)
-(void)onInvited:(NSString *)sponsor
         userIds:(NSArray<NSString *> *)userIds
     isFromGroup:(BOOL)isFromGroup
        callType:(CallType)callType
NS_SWIFT_NAME(onInvited(sponsor:userIds:isFromGroup:callType:));

接受邀请

[[TRTCCalling shareInstance] accept];

接受邀请之后,组件会执行进入房间的音频采集传输操作以及通过IM通知接收方接受邀请。

[self enterRoom];

/**
 *  IMSDK方法
 *  接收方接受邀请
 *  @note 不能接受不是针对自己的邀请,请在收到 onReceiveNewInvitation 回调的时候先判断 inviteeList 有没有自己,如果没有自己,不能 accept 邀请。
 */
- (void)accept:(NSString *)inviteID data:(NSString *)data succ:(V2TIMSucc)succ fail:(V2TIMFail)fail;

拒绝通话

[[TRTCCalling shareInstance] reject];

拒绝通话内部实现方法

//调用组件的以下方法,并传入cation的值为CallAction_Reject
- (NSString *)invite:(NSString *)receiver action:(CallAction)action model:(CallModel *)model;

//最终调用IMSDK的
/**
 *  接收方拒绝邀请
 *
 *  @note 不能拒绝不是针对自己的邀请,请在收到 onReceiveNewInvitation 回调的时候先判断 inviteeList 有没有自己,如果没有自己,不能 reject 邀请。
 */
- (void)reject:(NSString *)inviteID data:(NSString *)data succ:(V2TIMSucc)succ fail:(V2TIMFail)fail;

接收、邀请超时

当邀请发起后一段时间(默认30秒)没有回复的时候,接收方会通过组件回调

/// 通话超时的回调 | timeout callback
-(void)onCallingTimeOut;

邀请方会通过组件调用

/// 无回应回调-仅邀请者受到通知,其他用户应使用 onUserEnter |
/// no response callback only worked for Sponsor, others should use onUserEnter)
/// - Parameter uid: userid
-(void)onNoResp:(NSString *)uid

如果通话邀请方在多个接收均未应答时会回调

/// 主动挂断通话
- (void)hangup;

并且每个接收方都会通过组件回调

/// 当前通话被取消回调 | current call had been canceled callback
-(void)onCallingCancel:(NSString *)uid
NS_SWIFT_NAME(onCallingCancel(uid:));

中途加入与离开

如果需要离开当前多人通话可以调用

/// 主动挂断通话
- (void)hangup;

如果通话中有用户中途加入或离开,那么其他用户均会接收到以下两个回调

/// 进入通话回调 | user enter room callback
/// - Parameter uid: userid
-(void)onUserEnter:(NSString *)uid

/// 离开通话回调 | user leave room callback
/// - Parameter uid: userid
-(void)onUserLeave:(NSString *)uid
NS_SWIFT_NAME(onUserLeave(uid:));

多人视频通话

对人视频通话与多人语音通话流程基本一致,在组件中调用的API是一致的,需要注意传入的callType类型为CallType_Video。

/// 发起多人通话
/// @param userIDs 被邀请方ID列表
/// @param type 通话类型:视频/语音
/// @param groupID 群组ID,可选参数
- (void)groupCall:(NSArray *)userIDs
             type:(CallType)type
          groupID:(NSString * _Nullable)groupID
NS_SWIFT_NAME(groupCall(userIDs:type:groupID:));

在收到邀请后同语音回调相同会走以下方法,并同样使用语音的接受、拒绝邀请方法。

/// 被邀请通话回调 | invitee callback
/// - Parameter userIds: 邀请列表 (invited list)
-(void)onInvited:(NSString *)sponsor
         userIds:(NSArray<NSString *> *)userIds
     isFromGroup:(BOOL)isFromGroup
        callType:(CallType)callType
NS_SWIFT_NAME(onInvited(sponsor:userIds:isFromGroup:callType:));

如果对方接受邀请后打开了摄像头会回调以下方法

- (void)onUserVideoAvailable:(NSString *)uid available:(BOOL)available;

这时即可观看对方视频画面,可使用

[[TRTCCalling shareInstance] startRemoteView:uid view:renderView];

停止观看视频,可使用

[[TRTCCalling shareInstance] stopRemoteView:uid];

如需要更加详细的TRTCSDK的API可在SDK内查找TRTCCloud文件及查看或者看在线文档,并根据自己的需求对其进行封装等。

API头文件

离线接听

以上均为在线场景的接听功能,如果离线要如何做呢?

这就需要用前面文章配置的推送了。

  1. 申请 Apple 推送证书,具体操作请参见 Apple 推送证书申请
  2. 在后台及客户端配置离线推送,具体操作请参见 离线推送(iOS)
  3. 修改 login 函数中的 param.busiId 为对应证书 ID。
正文完