iOS SDK 如何进行互动

互动准备

  1. 注册微吼开发者账号

  2. 创建应用 获取AppID

  3. 设置应用Bundle ID

  4. 获取互动房间ID roomId

  5. 获取互动房间包含各种权限的access_token

  1. 获取旁路直播房间ID liveRoomId

工程配置

在开始使用sdk之前,我们要配置好IDE和创建基础的工程代码。相关内容在【工程配置】中有详细说明。

注意:

  1. 参与互动只能在真机环境下运行
  2. 互动库最低支持iOS9.0

时序图

注:虚线框部分请根据自身产品需求决定流程是否进行。

集成步骤简述

0、创建本地摄像头预览View,会在第3步中使用(可以在上麦推流之前,不上麦也可以不创建) 1、进入房间 2、接收他人互动画面 3、收到可以上麦代理,上麦(推流) 4、下麦(停止推流) 5、离开房间、销毁房间

代码对接

1: 引入互动SDK头文件

#import "VHInteractiveRoom.h"

2: 创建 VHInteractiveRoom 对象

先创建一个 VHInteractiveRoom 对象,我们后面主要用它来完成互动连麦等操作。

// 创建互动房间并设置 互动房间代理
_room = [[VHInteractiveRoom alloc] init];
self.room.delegate = self;

3: 进入互动房间 enterRoom

  • roomId 互动房间ID
  • accessToken 互动房间包含各种权限的accessToken
NSString* roomId      = @"inav_xxxxxx";
NSString* accessToken = @"xxxxxxxxxx";
[self.room enterRoomWithRoomId:roomId accessToken:accessToken];

4: 接收连麦他人视频 VHRenderView

renderViewsById 房间中所有其他上麦人视频view 是 以streamId 为 key VHRenderView 实例为 value 的 字典

以下是两个他人上下麦的代理方法,用于处理视频展示方式

  • 有人上麦
- (void)room:(VHInteractiveRoom *)room didAddAttendView:(VHRenderView *)attendView
{
//布局连麦界面 renderViewsById 房间中所有其他上麦人视频view
    [self updateData:self.room.renderViewsById changeView:attendView];
//上麦人id
     NSLog(@"%@",attendView.userId);
}
  • 有人下麦
- (void)room:(VHInteractiveRoom *)room didRemovedAttendView:(VHRenderView *)attendView
{
//布局连麦界面 renderViewsById 房间中所有其他上麦人视频view
    [self updateData:self.room.renderViewsById changeView:attendView];
//下麦人id
     NSLog(@"%@",attendView.userId);
}

5: 创建摄像头 cameraView

/*
 * 创建本地摄像头view
 * 默认参数 使用服务器配置参数
 */
VHRenderView*  cameraView = [[VHRenderView alloc]initCameraViewWithFrame: frame];

/*
 * 创建本地摄像头view 使用自定义 视频参数
 * type       type 推流清晰度设置
 * @param options   type = VHPushTypeCUSTOM有效   @{VHVideoWidthKey:@(192),VHVideoHeightKey:@(144),VHVideoFpsKey:@(30),VHMaxVideoBitrateKey:@(200)}
 */
VHRenderView*  cameraView = [[VHRenderView alloc]initCameraViewWithFrame: frame pushType:self.ilssType options:self.ilssOptions];

6: 开始推流 即上麦 publishWithCameraView

注:此接口需收到 room: canPublish: type: 代理方法后调用

cameraView 即上步中创建的本地摄像头 view

[self.room publishWithCameraView:self.cameraView];

7: 停止推流 即下麦 unpublish

[self.room unpublish];

8: 开启/关闭 旁路直播

注:开启旁路直播需 收到 room: didPublish: 代理方法后调用

  • liveRoomId
[self.room publishAnotherLive:isOpen liveRoomId:liveRoomId completeBlock:block];

9: 离开互动房间 leaveRoom

[self.room leaveRoom];

事件处理

  • 互动房间状态监听

1: 错误回调 error

- (void)room:(VHInteractiveRoom *)room error:(NSError*)error {
    if(room.status == VHInteractiveRoomStatusError)
    {
        [self.infoDict removeAllObjects];
        [self updateData:nil changeView:nil];
    }
    
    NSString *str = [NSString stringWithFormat:@"%@(%ld)",error.domain,(long)error.code];
    [self showMsg:str afterDelay:2];
//    [self showCallConnectViews:YES updateStatusMessage:[NSString stringWithFormat:@"Room error: %@", str]];
}

2: 房间状态回调 didChangeStatus

- (void)room:(VHInteractiveRoom *)room didChangeStatus:(VHInteractiveRoomStatus)status {
    switch (status) {
        case VHInteractiveRoomStatusDisconnected:
            [self showCallConnectViews:YES updateStatusMessage:@"已离开互动房间"];
            [self.infoDict removeAllObjects];
            [self updateData:nil changeView:nil];
            break;
        default:
            break;
    }
}

3: 有人进入房间回调 didEnterRoom

- (void)room:(VHInteractiveRoom *)room didEnterRoom:(NSString *)third_user_id {
    if( [DEMO_Setting.third_party_user_id isEqualToString:third_user_id])
        [self showCallConnectViews:NO updateStatusMessage:@"已进入互动房间"];
    else
        [self showMsg:[NSString stringWithFormat:@"%@ 进入房间",third_user_id] afterDelay:2];

    [self updateData:self.room.renderViewsById  changeView:nil];
    // We get connected and ready to publish, so publish.
}

4: 离开房间成功回调 didLeaveRoom

- (void)room:(VHInteractiveRoom *)room didLeaveRoom:(NSString *)third_user_id isKickOutRoom:(BOOL)isKickOut
{
    if( [DEMO_Setting.third_party_user_id isEqualToString:third_user_id])
        if(isKickOut)
        {
            [self showMsg:@"您已被管理员踢出房间" afterDelay:2];
            [self showCallConnectViews:NO updateStatusMessage:@"您已被管理员踢出房间"];
        }
        else
            [self showCallConnectViews:NO updateStatusMessage:@"已离开互动房间"];
    else
        [self showMsg:[NSString stringWithFormat:@"%@ 离开房间",third_user_id] afterDelay:2];
}

5:有人上麦(推流)回调 didAddAttendView

- (void)room:(VHInteractiveRoom *)room didAddAttendView:(VHRenderView *)attendView
{
    //布局连麦界面 renderViewsById 房间中所有上麦人视频view
    [self updateData:self.room.renderViewsById changeView:attendView];

//    NSString *name = attendView.attributes[@"name"];
//    NSString *name = attendView.userId;
//    [self showMsg:[NSString stringWithFormat:@"%@ 已上麦",name] afterDelay:2];
}

6:有人下麦(停止推流)回调 didAddAttendView

- (void)room:(VHInteractiveRoom *)room didRemovedAttendView:(VHRenderView *)attendView
{
    [self updateData:self.room.renderViewsById changeView:attendView];
//    NSString *name = attendView.attributes[@"name"];
//    NSString *name = attendView.userId;
//    [self showMsg:[NSString stringWithFormat:@"%@ 已下麦",name]  afterDelay:2];
}

7:收到别人上麦(推流)申请回调 requestPublish

#pragma mark - 上下麦推流信息回调
/*
 * 收到别人上麦申请 调用审核申请上麦接口回复
 */
- (void)room:(VHInteractiveRoom *)room requestPublish:(NSString *)third_user_id
{
    __weak typeof(self) wf = self;
    [JXTAlertView showAlertViewWithTitle:@"申请上麦"
                                 message:[NSString stringWithFormat:@"%@ 申请上麦",third_user_id]
                       cancelButtonTitle:@"忽略" buttonIndexBlock:^(NSInteger buttonIndex) {
                           switch (buttonIndex) {
                               case 1:
                                   [wf.room acceptPublishRequest:YES thirdUserId:third_user_id];
                                   break;
                               case 2:
                                   [wf.room acceptPublishRequest:NO thirdUserId:third_user_id];
                                   break;
                               default:
                                   break;
                           }
                       } otherButtonTitles:@"同意",@"拒绝", nil];
}

8: 收到可以上麦(推流)回调 canPublish

/*
 *
 * canPublish YES 可以上麦推流 NO 不可上麦推流
 * type 1、进入房间后有无上麦推流权限 2、申请上麦 审核后有无上麦推流权限 3、收到邀请上麦消息 获得上麦推流权限
 */
- (void)room:(VHInteractiveRoom *)room canPublish:(BOOL)canPublish type:(int) type{
    switch (type) {
        case 1:
        {
            if(canPublish)
                [self publish];
            else
                [self showMsg:@"没有上麦权限,请申请上麦" afterDelay:2];
        }
            break;
        case 2:
        {
            if(canPublish)
            {
                [self showMsg:@"管理员同意您上麦" afterDelay:2];
                [self publish];
            }
            else
                [self showMsg:@"管理员拒绝了您上麦请求" afterDelay:2];
        }
            break;
        case 3:
        {
            __weak typeof(self) wf = self;
            [JXTAlertView showAlertViewWithTitle:@"管理员邀请您上麦"
                                         message:@"管理员邀请您上麦"
                               cancelButtonTitle:@"忽略" buttonIndexBlock:^(NSInteger buttonIndex) {
                                   switch (buttonIndex) {
                                       case 1:
                                       {
                                           if(canPublish)
                                               [wf publish];
                                       }
                                           break;
                                       case 2:
                                           [wf.room refusePublish];
                                           break;
                                       default:
                                           break;
                                   }
                               } otherButtonTitles:@"同意",@"拒绝", nil];
        }
            break;
            
        default:
            break;
    }
}

9: 收到上麦(推流)成功回调 didPublish

/*
 * 推流成功
 */
- (void)room:(VHInteractiveRoom *)room didPublish:(VHRenderView *)cameraView
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self didPublish:cameraView.streamId];
        [self showCallConnectViews:NO updateStatusMessage:@"已上麦"];
    });
}

10: 收到下麦(停止推流)成功回调 didUnpublish

/*
 * 停止推流成功
 * reason  "主动下麦" "被动下麦"
 */
- (void)room:(VHInteractiveRoom *)room didUnpublish:(NSString *)reason
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self didUnPublish];
        [self showCallConnectViews:NO updateStatusMessage:@"已下麦"];
    });
}

11: 收到房间人员信息变化回调 userChangeStatus

/*
 * 房间人员信息变化
 */
- (void)room:(VHInteractiveRoom *)room userChangeStatus:(int)status onlineNum:(NSInteger)onlineNum
{
    [self updateUserListData];
    self.onlineNumLabel.text = [NSString stringWithFormat:@"在线 %ld 人",(long)onlineNum];
}

其他相关文档

  1. 快速开始
  2. 互动模块参考手册