文档反馈
文档反馈

客户端实现(iOS)

本文档为您展示通过 SDK 实现 PK 连麦场景的相关步骤,帮助您在业务中实时音视频通话、互动直播、连麦 PK、文字聊天、收发礼物等 IM、音视频通话 2.0 和互动直播 2.0 在 PK 连麦场景下的相关能力。

前提条件

集成 SDK

请参考下表,将相应的 SDK 或服务集成到您的项目中。

产品 SDK 下载 集成文档
IM 即时通讯(含信令) IM SDK(含信令) 集成 SDK
音视频通话 2.0 NERTC SDK 集成 SDK

实现 PK 连麦

步骤1 初始化配置

  1. 业务应用服务器配置。

    正式开始业务流程之前,您需要通过业务应用服务器完成以下步骤。

    1. 调用创建频道服务端接口,在返回参数中获取推拉流地址。详细操作请参考直播管理相关 API
    2. 创建音视频房间。详细操作请参考创建房间
    3. 创建聊天室。业务服务器维护聊天室列表及礼物信息。详细操作请参考创建聊天室
  2. 初始化并登陆 IM。

    初始化的详细说明请参考初始化 IM SDK

  3. 加入聊天室。

    加入聊天室后可以参与文字聊天。Demo 中的逻辑规定,只有加入聊天室后才能开启直播。

  4. 设置音频参数和属性。

    您可以根据对音质、声道、场景等的不同需求,通过 setAudioProfile 方法灵活设置音频属性,获得最佳实时互动效果。也可以通过 setLocalVideoConfig 设置视频发送配置。

示例代码

//1. 初始化并登陆 IM。

//2. 加入聊天室。
    // 进入聊天室
    - (void)enterChatroom:(NIMChatroomEnterRequest *)request
           completion:(nullable NIMChatroomEnterHandler)completion;

//3. 设置音频参数和属性。

    // 设置视频发送配置(帧率/分辨率)
    [[NERtcEngine sharedEngine] setLocalVideoConfig:config];

    // 设置音频质量
    [[NERtcEngine sharedEngine] setAudioProfile:profile scenario:scenario];

步骤2 主播端开播

经过一系列初始化配置之后,主播端可以开启单人直播。

  1. 设置直播模式。

    在互动直播的场景中,建议在加入房间前,通过 setChannelProfile 接口设置房间模式为直播模式。

  2. 启动音视频流,并打开推流开关。

    调用 enableLocalVideo 开启本地视频采集和发送,并通过 setParameters 打开推流开关。

    注意:开启推流开关之后,主播或管理员创建推流任务之后才正式启动旁路推流。

  3. 设置本地视频画布。

    通过 setupLocalVideoCanvas 设置本地视频画布,确定本地采集的视频画面。

  4. 初始化 NERTC SDK 并注册监听。 初始化的详细说明请参考初始化 NERTC SDK

  5. 加入音视频房间。

    • 由于您已在步骤 1 中创建了音视频房间,客户端可以直接通过参数 ChannelName 加入指定房间。若未提前创建房间,客户端也可以直接通过 joinChannel 直接加入房间,SDK 会在加入时自动创建一个房间。
    • 安全模式下加入房间需要填写获取到的 Token;非安全模式下,Token 请设置为 null。
  6. 配置推流状态监听。

    主播或连麦者参与互动直播的过程中,可以通过 NERtcCallback 的 onNERTCEngineLiveStreamState 来监听推流状态。

  7. 新增并维护推流任务。

    在成功加入房间后,通过 addLiveStreamTask 创建推流任务,将通话房间内的多媒体数据推至 CDN。常见的推流状态请参考互动直播推流状态

    您也可以通过服务端 API 创建推流任务。

示例代码

//1. 设置直播模式。
    // 设置频道场景(直播)
    [[NERtcEngine sharedEngine] setChannelProfile:kNERtcChannelProfileLiveBroadcasting];

//2. 启动音视频流,并打开推流开关。
    //启动音视频流
    [[NERtcEngine sharedEngine] enableLocalAudio:YES];
    [[NERtcEngine sharedEngine] enableLocalVideo:YES];

    // 打开推流,回调摄像头采集数据
    NSDictionary *params = @{
        kNERtcKeyPublishSelfStreamEnabled: @YES,    // 打开推流
        kNERtcKeyVideoCaptureObserverEnabled: @YES  // 将摄像头采集的数据回调给用户
    };
    [[NERtcEngine sharedEngine] setParameters:params];


//3. 设置本地视频画布。
    - (int)setupLocalVideoCanvas:(NERtcVideoCanvas *)canvas;

//4. 初始化 NERTC SDK 并注册监听。
    NERtcEngineContext *context = [[NERtcEngineContext alloc] init];
    context.engineDelegate = self;
    context.appKey = appkey;
    [[NERtcEngine sharedEngine] setupEngineWithContext:context];

//5. 加入音视频房间。
    // 加入频道
    - (int)joinChannelWithToken:(NSString *)token
                channelName:(NSString *)channelName
                      myUid:(uint64_t)uId
                 completion:(NERtcJoinChannelCompletion)completion;

//6. 配置推流状态监听。
    - (void)onNERTCEngineLiveStreamState:(NERtcLiveStreamStateCode)state 
                              taskID:(NSString *)taskID 
                                 url:(NSString *)url;
//7. 新增并维护推流任务。

  // 示例
  //先初始化推流任务
  NERtcLiveStreamTaskInfo *info = [[NERtcLiveStreamTaskInfo alloc] init];
  //taskID 可选字母、数字,下划线,不超过64位
  info.taskID = taskID;    
  // 设置推互动直播推流地址,一个推流任务对应一个推流房间
  info.streamURL = pushUrl;   
  // 设置是否进行互动直播录制,请注意与音视频通话录制区分。
  info.serverRecordEnabled = NO;  
  // 设置推音视频流还是纯音频流
  info.lsMode = enableVideo ? kNERtcLsModeVideo : kNERtcLsModeAudio;

  //设置整体布局
  NERtcLiveStreamLayout *layout = [[NERtcLiveStreamLayout alloc] init];
  layout.width = 720;      //整体布局宽度
  layout.height = 1280;  //整体布局高度
  layout.backgroundColor = (red & 0xff) << 16 | (green & 0xff) << 8 | (blue & 0xff);
  info.layout = layout;
  // 设置直播成员布局
    NERtcLiveStreamUserTranscoding *user1 = [[NERtcLiveStreamUserTranscoding alloc] init];
    user1.uid = uid1;
    user1.audioPush = true;        // 推流是否发布user1的音频
    user1.videoPush = enableVideo; // 推流是否发布user1的视频
    if (user1.videoPush) {
        // 如果发布视频,需要设置一下视频布局参数
        user1.x = 10; // user1 的视频布局x偏移,相对整体布局的左上角
        user1.y = 10; // user1 的视频布局y偏移,相对整体布局的左上角
        user1.width = 180; // user1 的视频布局宽度
        user1.height = 320; //user1 的视频布局高度
        user1.adaption = kNERtcLsModeVideoScaleCropFill;
        }

  // 设置第n位直播成员布局
    NERtcLiveStreamUserTranscoding *usern = [[NERtcLiveStreamUserTranscoding alloc]init];
    usern.uid = uidn;
    usern.audioPush = true;
    usern.videoPush = enableVideo;
    if (usern.videoPush) {
       usern.adaption = kNERtcLsModeVideoScaleCropFill;
       usern.x = user1.x + user1.width + 10;
       usern.y = user1.y + user1.height + 10;
       usern.width = 320;
       usern.height = 640;
    }
    layout.users = @[user1,...,usern];


  //配置背景占位图片,可以不配置。
    NERtcLiveStreamImageInfo *imageInfo = [[NERtcLiveStreamImageInfo alloc] init];
    imageInfo.url = url;      
    imageInfo.x = 0;
    imageInfo.y = 0;
    imageInfo.width = 720;
    imageInfo.height = 1280;
    layout.bgImage = imageInfo;
    //调用 addLiveStreamTask 接口添加推流任务
    int ret = [[NERtcEngine sharedEngine] addLiveStreamTask:info
                                                 compeltion:^(NSString * _Nonnull taskId, kNERtcLiveStreamError errorCode) {

        NSString *toast = !errorCode ? @"添加成功" : [NSString stringWithFormat:@"添加失败 errorcode = %d",errorCode];
        MakeToast(toast);
    }];

    if (ret != 0) {
        MakeToast(@"调用添加推流任务失败");
    }

步骤3 观众端观看

  1. 观众端加入聊天室。

    观众端加入聊天室之后可以进行文字互动、打赏等操作。

  2. 观众端通过拉流地址拉流观看直播。

    观众端通过播放器实现拉流收听,您可以使用网易云信提供的播放器 SDK 实现,详细操作请参考播放器 SDK 快速入门

步骤4 主播连麦 PK

在 PK 连麦场景 Demo 中,主播 A 邀请主播 B 进行连麦 PK,主播 B 同意 PK 申请后,主播 A 和 B 删除推流任务、退出原有互动直播房间,并且请求服务器创建一个新的互动直播房间用于连麦 PK。主播 A 和 B 重新加入新房间之后,使用原有的推流地址重新推流,在新的互动直播房间中进行连麦 PK 即可。

注意

操作步骤

  1. 主播 A 通过信令发起 PK 邀请,并创建信令房间。

    通过信令可以直接呼叫并创建信令频道,用于邀请其他主播进行 PK。

  2. 主播 B 接受 PK 邀请,并自动加入信令房间。

    其中,参数 NIMSignalingAcceptRequest 中的 autoJoin 表示接受邀请后是否自动加入房间,请配置为 YES。主播 B 也可以拒绝邀请,详细操作请查看示例代码。

  3. 主播 A 和主播 B 删除推流任务、退出原房间并加入新的直播房间。

    • 您可以通过客户端删除推流任务,或通过服务端 API 删除推流任务。详细信息请参考互动直播快速入门服务端 API
    • 主播 A 和主播 B 加入新直播房间的详细流程,请参考步骤2
  4. 主播端设置远端画布。

    1. 监听远端用户加入频道与监听远端视频流发布。
    2. 设置远端画布、订阅远端视频流。
  5. 新增推流任务,观众端重新拉流。

    新的推流任务中需要添加两个主播的原推流地址,观众端拉流时无需切换拉流地址。

示例代码

//1. 主播 A 通过信令发起 PK 邀请,并创建信令房间。
    // 呼叫
    - (void)signalingCall:(NIMSignalingCallRequest *)request
           completion:(nullable NIMSignalingCallBlock)completion;

//2. 主播 B 接受 PK 邀请,并自动加入信令房间。
    // 接受对方邀请并自动加入频道,参数 NIMSignalingAcceptRequest 中的 autoJoin 表示接受邀请后是否自动加入房间,请配置为 YES。
    - (void)signalingAccept:(NIMSignalingAcceptRequest *)request
             completion:(nullable NIMSignalingAcceptBlock)completion;
    // 拒绝邀请
    - (void)signalingReject:(NIMSignalingRejectRequest *)request
             completion:(nullable NIMSignalingOperationBlock)completion;

//3. 主播 A 和主播 B 删除推流任务、退出原房间并加入新的直播房间。

    // 先退出当前频道
    [NERtcEngine.sharedEngine leaveChannel];;   离开频道

    // 在退出成功的代理方法里,加入新频道
    - (int)joinChannelWithToken:(NSString *)token
                    channelName:(NSString *)channelName
                        myUid:(uint64_t)uId
                    completion:(NERtcJoinChannelCompletion)completion;

//4. 主播端设置远端画布。
    //监听远端用户加入频道与监听远端视频流发布。
    - (void)onNERtcEngineUserDidJoinWithUserID:(uint64_t)userID
        userName:(NSString *)userName;
    - (void)onNERtcEngineUserVideoDidStartWithUserID:(uint64_t)userID videoProfile:(NERtcVideoProfileType)profile;
    //设置远端画布、订阅远端视频流。
    - (int)setupRemoteVideoCanvas:(NERtcVideoCanvas *)canvas forUserID:(uint64_t)userID;
    - (int)subscribeRemoteVideo:(BOOL)subscribe                  
        forUserID:(uint64_t)userID                  
        streamType:(NERtcRemoteVideoStreamType)streamType;


//5. 新增推流任务,观众端重新拉流。

步骤5 结束直播

  1. 调用接口 leaveChannel 离开频道。
  2. 调用接口 destroyEngine 销毁音视频实例。

    在收到 onNERtcEngineDidLeaveChannelWithResult 之后执行 destroyEngine 销毁实例。

示例代码

//1. 离开频道。   
    //UI 挂断按钮事件- (IBAction)onHungupAction:(UIButton *)sender {
    [NERtcEngine.sharedEngine leaveChannel];
    [self dismiss];
    }

//2. 销毁音视频实例。
    - (void)dealloc {
        [NERtcEngine destroyEngine]; //销毁实例
    }
×

反馈成功

非常感谢您的反馈,我们会继续努力做得更好。