互动直播 2.0
iOS
新手接入指南
产品简介
产品介绍
功能特性
产品优势
应用场景
基本概念
使用限制
更新日志
体验 Demo
下载 SDK 和 示例代码
快速开始
接入流程
创建应用
开通服务
集成 SDK
实现互动直播
Token 鉴权
高级 Token 鉴权
基础功能
设置音频属性
设置视频属性
通话音量管理
屏幕共享
进阶功能
音频管理
客户端音频录制
原始音频数据
耳返
美声变声与混响
音效与伴音
自定义音频采集与渲染
设置音频订阅优先级
音频裸流传输
视频管理
视频截图
水印
云信美颜
第三方美颜
自定义视频采集
视频图像畸变矫正
虚拟背景
视频裸流传输
设备管理
音频设备管理
视频设备管理
体验提升
监测发言者音量
媒体补充增强信息
通话中质量监测
旁路推流
旁路推流
旁路推流画面布局
媒体流管理
视频流回退
跨房间媒体流转发
媒体流加密
AI 融合功能
AI 超分
AI 降噪
最佳实践
音视频参数配置推荐
Audio Session 使用建议
客户端 API
iOS API 参考
错误码
服务端 API
控制台指南
常见问题处理
FAQ
错题集
服务协议

实现互动直播

更新时间: 2022/09/08 22:59:04

网易云信互动直播产品的基本功能包括音视频通话和连麦直播,当您成功初始化 SDK 之后,您可以简单体验本产品的基本业务流程,例如主播加入房间、观众CDN拉流、连麦者上下麦、结束直播等。本文档为您展示互动直播提供的基本业务流程。

前提条件

请确认您已完成以下操作:

主播加入房间

步骤一 导入类

在项目中导入 NERtcSDK 类:

  #import <NERtcSDK/NERtcSDK.h>

步骤二 初始化

调用 setupEngineWithContext 方法完成初始化。

自 V4.4.0 版本起,初始化之前无需通过 setParameters 方法的 kNERtcKeyPublishSelfStreamEnabled 字段打开推流开关。加入房间并创建推流任务后,房间中所有成员的音视频流均可以进行混流并推流至 CDN。

示例代码如下:

  //初始化
  @interface Myapp ()<NERtcEngineDelegateEx>
  ...
  NERtcEngine *coreEngine = [NERtcEngine sharedEngine];
  NERtcEngineContext *context = [[NERtcEngineContext alloc] init];
  //设置通话相关信息的回调
  context.engineDelegate = self;
  //设置当前应用的 App Key
  context.appKey = AppKey;
  [coreEngine setupEngineWithContext:context];
  ...

步骤三 设置本地视图

初始化成功后,可以设置本地视图,来预览本地图像。您可以在加入房间之前预览,或在加入房间后预览。

  • 加入房间前预览。

    1. 调用 setupLocalVideoCanvasstartPreview(streamType),在加入房间前设置本地视图,预览本地图像。

    示例代码如下:

    // 示例
    NERtcVideoCanvas *canvas = [[NERtcVideoCanvas alloc] init];
    canvas.container = self.localUserView;
    // 设置本地视频画布
    [NERtcEngine.sharedEngine setupLocalVideoCanvas:canvas];
    // 以开启本地视频主流预览为例
    [NERtcEngine.sharedEngine startPreview:kNERtcStreamChannelTypeMainStream];
    
    1. 若要结束预览,或者准备加入房间时,调用 stopPreview(streamType) 方法停止预览。

stopPreview(streamType)streamType 参数请与 startPreview(streamType) 的保持一致,即同为主流或辅流的开启和停止预览。

  • 加入房间后预览。

    在成功加入房间后,调用 enableLocalVideo 方法进行视频的采集发送与预览。

    示例代码如下:

    //以开启本地视频主流采集并发送为例
    [NERtcEngine.sharedEngine enableLocalVideo:YES,kNERtcStreamChannelTypeMainStream];
    //设置本地预览画布
    NERtcVideoCanvas *canvas = [[NERtcVideoCanvas alloc] init];
    canvas.container = self.localUserView;
    [NERtcEngine.sharedEngine setupLocalVideoCanvas:canvas];
    

步骤四 设置直播模式

在互动直播的场景中,建议在加入房间前,调用 setChannelProfile 方法设置房间模式为直播模式。当前默认为通信模式。

示例代码如下:

  // kNERtcChannelProfileCommunication-通信模式
  // kNERtcChannelProfileLiveBroadcasting-直播模式
  [NERtcEngine.sharedEngine setChannelProfile:kNERtcChannelProfileLiveBroadcasting];

步骤五 加入房间

加入房间前,请确保已完成初始化相关事项。若您的业务中涉及呼叫邀请等机制,建议通过 信令 实现。

调用 joinChannelWithToken:channelName:myUid:completion: 方法加入房间。

示例代码如下:

  // 示例
  [NERtcEngine.sharedEngine joinChannelWithToken:@""
                                     channelName:roomId
                                           myUid:userId
                                      completion:^(NSError * _Nullable error, uint64_t channelId, uint64_t elapesd) {
                                                          if (error) {
                                                              //加入失败
                                                          } else {
                                                              //加入成功
                                                          }
                                        }];

参数说明

参数 说明
Token 安全认证签名(NERTC Token)。
  • 调试模式下:可设置为 null。产品默认为安全模式,您可以在网易云信控制台将鉴权模式修改为调试模式,具体请参见Token 鉴权
    调试模式的安全性不高,请在产品正式上线前修改为安全模式。
  • 产品正式上线后:请设置为已获取的NERTC Token。安全模式下必须设置为获取到的 Token 。若未传入正确的 Token 将无法进入房间。

    推荐使用安全模式

channelName 房间名称,长度为 1 ~ 64 字节。目前支持以下 89 个字符:a-z, A-Z, 0-9, space, !#$%&()+-:;≤.,>? @[]^_{|}~"。
设置相同房间名称的用户会进入同一个通话房间。
您也可以在加入通道前,通过创建房间接口创建房间。加入房间时,若传入的 {channelName} 未事先创建,则云信服务器内部将为其自动创建一个名为 {channelName} 的通话房间。
myUid 用户的唯一标识 id,为数字串,房间内每个用户的 uid 必须是唯一的。此 uid 为用户在您应用中的 ID,请在您的业务服务器上自行管理并维护。

步骤六 推流任务管理

在成功加入房间后,需要通过 NERtcLiveStreamTaskInfo 设置推流任务,将通话房间内的多媒体数据推至 CDN。典型的业务场景里是由主播进行设置推流任务。

推流任务也可以通过服务端 API 进行管理,请根据您的业务需求选择合适的方式。

  • 此处的主播业务层面的角色,SDK 体系内不区分主播与连麦者。
  • 推流任务中,需要设置互动直播的CDN推流地址,请在合适的时机创建直播房间,将获取到的推流地址传入推流任务。
  • 添加推流任务时,需要设置布局参数,您可以参考旁路推流画面布局完成设置。
  • 推流任务与通话绑定,当通话结束后,推流任务也会自动随之销毁。
  • 一通通话,即一个channelId同时最多对应 6 个不同的推流任务。

增加推流任务

音视频房间中默认没有推流任务,您需要在启动直播前调用 addLiveStreamTask:compeltion: 方法增加推流任务。

示例代码(增加推流任务)
  //初始化推流任务
  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;
      user1.zOrder = 1;
      }
    
  //设置第n位推流成员布局
  NERtcLiveStreamUserTranscoding *usern = [[NERtcLiveStreamUserTranscoding alloc]init];
  usern.uid = uidn;
  usern.audioPush = true;
  usern.videoPush = enableVideo;
  if (usern.videoPush) {
      usern.x = user1.x + user1.width + 10;
      usern.y = user1.y + user1.height + 10;
      usern.width = 320;
      usern.height = 640;
      usern.adaption = kNERtcLsModeVideoScaleCropFill;
      usern.zOrder = 1;
  }
  layout.users = @[user1,...,usern];

  //设置音视频流编码参数
  NERtcLiveConfig *config = [[NERtcLiveConfig alloc] init];
  //设置是否开启推流成员离线时的占位图
  config.interruptedPlaceImage = false;
  //设置是否开启单路视频透传开关
  config.singleVideoPassthrough = false;
  //设置音频推流码率
  config.audioBitrate = 192 kbps;
  //设置音频推流采样率
  config.sampleRate = kNERtcLiveStreamAudioSampleRate48000;
  //设置音频编码规格
  config.audioCodecProfile= kNERtcLiveStreamAudioCodecProfileLCAAC;
  //设置音频推流声道数
  config.channels = 2;
  layout.config = config;

  //设置占位图片布局(可选)
  //原 bgImg 字段仍保留,仅可设置一张占位图,若您同时配置了两个字段,则以 bgImages 配置为准
  NERtcLiveStreamImageInfo *image1 = [[NERtcLiveStreamImageInfo alloc] init];
  image1.url = url; //image1的URL   
  image1.x = 10; //image1的布局x偏移,相对整体布局的左上角
  image1.y = 10; //image1的布局y偏移,相对整体布局的左上角
  image1.width = 320; //image1的宽度
  image1.height = 640; //image1的高度
  image.zOrder = 0; //image1的图层编号

  //设置第n张占位图片布局
  NERtcLiveStreamImageInfo *imagen = [[NERtcLiveStreamImageInfo alloc] init];
  imagen.url = url; //不同的占位图需要设置不同的url 
  imagen.x = image1.x + image1.width + 10; 
  imagen.y = image1.y + image1.height + 10; 
  imagen.width = 180; 
  imagen.height = 320; 
  image.zOrder = 0; //不同占位图可以设置不同的zOrder
  layout.bgImages = @[image1,...,imagen];
    
  //调用 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(@"调用添加推流任务失败");
  }

更新推流任务

当音视频通话房间内有人员进出或其他情况时,可以使用 – updateLiveStreamTask:compeltion: 方法更新推流任务。更新推流任务时,会覆盖之前对于这条推流任务的所有配置。

示例代码(更新推流任务)
  // 初始化新推流任务。注意:其中的taskid为原推流任务id。
  NERtcLiveStreamTaskInfo *updateLiveTask1 = preLiveTask;
  ...

  // 更新推流任务
  int ret = [[NERtcEngine sharedEngine] updateLiveStreamTask:updateLiveTask1
                                                compeltion:^(NSString * _Nonnull taskId, kNERtcLiveStreamError errorCode) {

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

  if (ret != 0) {
    MakeToast(@"更新推流任务失败");
  }

删除推流任务

当本场互动直播准备结束时,可以通过 – removeLiveStreamTask:compeltion: 方法主动删除推流任务。

示例代码(删除推流任务)
  // 示例
  NSString *taskID = preLiveTask.taskID;

  int ret = [[NERtcEngine sharedEngine] removeLiveStreamTask:taskID
                                                compeltion:^(NSString * _Nonnull taskId, kNERtcLiveStreamError errorCode) {
    NSString *toast = !errorCode ? @"删除成功" : [NSString stringWithFormat:@"errorcode = %d",errorCode];
    MakeToast(toast);
  }];

  if (ret != 0) {
    MakeToast(@"删除推流任务失败");
  }

推流任务相关错误码

增加、更新与删除推流任务时,如果发生错误,回调接口通过错误码形式反馈错误原因。错误码 kNERtcLiveStreamError 如下:

错误码 含义
kNERtcLiveStreamErrorRequestIsInvaild = 1301 task请求无效,被后续操作覆盖
kNERtcLiveStreamErrorIsInvaild = 1400 task参数格式错误
kNERtcLiveStreamErrorRoomExited = 1401 已经退出房间
kNERtcLiveStreamErrorNumLimit = 1402 推流任务超出上限
kNERtcLiveStreamErrorDuplicateId = 1403 推流ID重复
kNERtcLiveStreamErrorNotFound = 1404 taskId任务不存在,或房间不存在
kNERtcLiveStreamErrorRequestErr = 1417 请求失败
kNERtcLiveStreamErrorInternalServerErr = 1500 服务器内部错误
kNERtcErrLsTaskInvalidLayout = 1501 布局参数错误
kNERtcErrLsTaskUserPicErr = 1502 用户图片错误

互动直播推流状态

主播/连麦者参与互动直播的过程中,可以通过 NERtcEngineLiveStreamObserver– onNERTCEngineLiveStreamState:taskID:url: 来监听推流状态。

常见的推流状态如下:

状态码 含义
kNERtcLsStatePushing = 505 推流中
kNERtcLsStatePushFail = 506 互动直播推流失败
kNERtcLsStatePushStopped = 511 推流结束

步骤七 设置远端视图

互动直播过程中,除了要显示本地的视频画面,通常也要显示参与互动的其他连麦者/主播的远端视频画面。

  1. NERtcEngineDelegate 通过以下回调获取相关信息:

  2. 在监听到远端用户加入房间或发布视频流后,本方可以通过 – setupRemoteVideoCanvas:forUserID: 方法设置远端用户视频画布,用于显示其视频画面。

    示例代码如下:

      NERtcVideoCanvas *canvas = [self setupRemoteCanvasWithUid:userID];
      [NERtcEngine.sharedEngine setupRemoteVideoCanvas:canvas forUserID:userID];
    
  3. 在监听到远端用户发布视频流后,本方可以通过 – subscribeRemoteVideo:forUserID:streamType: 方法对其发起视频流的订阅,来将对方的视频流渲染到视频画布上。

    示例代码如下:

      [NERtcEngine.sharedEngine subscribeRemoteVideo:YES
                                          forUserID:userID
                                          streamType:kNERtcRemoteVideoStreamTypeHigh];
    

步骤八 音频流

本地音频的采集发布和远端音频订阅播放是默认启动的,正常情况下无需开发者主动干预。

观众进行CDN拉流

当通话房间内有主播/连麦者发布多媒体流,且正确设置了推流任务时,通话房间外的观众可以通过 CDN 直播拉流地址进行拉流播放。云信同时提供播放器SDK组件供您使用,详细内容请参考直播-播放器 SDK

连麦者上下麦

步骤一 上麦

若正在进行 CDN 拉流播放的普通观众要上麦参与互动时,必须先停止 CDN 拉流,并释放播放器相关资源。然后按照主播加入房间流程,进行初始化、设置本地视图、设置直播模式、设置推流开关、加入通话房间、设置远端视图。

注意

  • 由于有新连麦者的加入,需要更新推流任务将新连麦者设置到推流布局中。操作步骤请参考更新推流任务。更新推流的任务操作,可以由主播执行,也可以由连麦者执行,也可以通过服务端API完成。
  • NERTC SDK 支持直播场景下的用户角色管理,角色包括主播和观众,默认以主播角色加入房间。调用 setChannelProfile 将通话设置为直播场景之后,可以通过 setClientRole 切换用户角色。

步骤二 下麦

若连麦者互动结束,需要下麦时,可以更新推流任务,在推流布局中剔除该连麦者。同时,连麦者退出通话房间,清理相关资源,重新进行播放器拉流或直接离开直播间。

通话房间内的其他用户可以通过NERtcEngineDelegate– onNERtcEngineUserDidLeaveWithUserID:reason: 来监听其他连麦者下麦。

结束互动直播

需要结束该场互动直播时,可以先删除推流任务,然后主播与连麦者退出通话房间,观众结束 CDN 拉流。

1. 退出通话房间

通过 leaveChannel 接口退出通话房间。

示例代码如下:

  // 退出通话房间
  [NERtcEngine.sharedEngine leaveChannel];

NERtcEngineDelegate 提供 – onNERtcEngineDidLeaveChannelWithResult: 来监听当前用户退出房间的结果。

2. 销毁实例

当确定 App 短期内不再使用音视频通话实例时,可以通过 destroyEngine 释放对应的对象资源。

示例代码如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

     [NERtcEngine destroyEngine];

 });
此文档是否对你有帮助?
有帮助
我要吐槽
  • 前提条件
  • 主播加入房间
  • 步骤一 导入类
  • 步骤二 初始化
  • 步骤三 设置本地视图
  • 步骤四 设置直播模式
  • 步骤五 加入房间
  • 步骤六 推流任务管理
  • 增加推流任务
  • 更新推流任务
  • 删除推流任务
  • 推流任务相关错误码
  • 互动直播推流状态
  • 步骤七 设置远端视图
  • 步骤八 音频流
  • 观众进行CDN拉流
  • 连麦者上下麦
  • 步骤一 上麦
  • 步骤二 下麦
  • 结束互动直播
  • 1. 退出通话房间
  • 2. 销毁实例