实现互动直播

更新时间: 2023/11/17 08:09:54

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

前提条件

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

网易云信 Web SDK 仅支持 HTTPS 协议或 localhost(http://127.0.0.1)。请勿使用 HTTP 协议在 localhost 之外访问项目,否则 Web 浏览器控制台会报错 NOT_SUPPORT 41001

主播加入房间

1. 引用文件

在项目相应的前端页面文件中,对 NIM_Web_NERTC_vx.x.x.js 文件进行引用。

  • import 方式引入:

    jsimport NERTC from '../../NIM_Web_NERTC_vx.x.x.js'
    
  • script 标签引入:

    js<script src="./NIM_Web_NERTC_vx.x.x.js"></script>
    

NERTC 中有两个重要类:

  • Client

    代表一个本地客户端。Client 类的方法提供了音视频通话的主要功能,例如加入房间、发布音视频流等。

  • Stream

    代表本地和远端的音视频流。Stream 类的方法用于定义音视频流对象的行为,例如流的播放控制、音视频的编码配置等。调用 Stream 方法时,请注意区分本地流和远端流对象。

2. 初始化

执行 createClient 方法创建 client 实例。

js  //示例
  //创建client实例
  rtc.client = NERTC.createClient({
    appkey: 'xxx', //您的 appkey
    debug: true, //是否开启调试日志
  });

3. 设置本地视图(可选)

初始化成功后,可以设置本地视图,预览本地图像。加入房间后,可以执行 publish 方法发布自己的多媒体流至流媒体,供其他用户订阅。

示例代码(设置本地视图)
js  //初始化本地流并且发布
  function initLocalStream() {
    //创建本端stream实例,销毁前无需重复创建
    rtc.localStream = NERTC.createStream({
      uid: uid,                      // 本端的uid
      audio: true,                   // 是否从麦克风采集音频
      microphoneId: microphoneId,    // 麦克风设备 deviceId,通过 getMicrophones() 获取
      video: true,                   // 是否从摄像头采集视频
      cameraId: cameraId             // 摄像头设备 deviceId,通过 getCameras() 获取
    })

    //启动本地音视频流,销毁前无需重复初始化
    rtc.localStream.init().then(()=>{
      console.warn('音视频初始化完成,播放本地视频')
      //用于播放视频的div元素
      let div = document.getElementById('local-container')
      //开始播放本地视频流
      rtc.localStream.play(div)
      //设置播放的视频容器大小    
      rtc.localStream.setLocalRenderMode({
        width: 180,
        height: 150,
        cut: true    // 是否裁剪
      })

      // 将本地音视频流发布至云信服务器,加入房间前不用执行此方法。
      rtc.client.publish(rtc.localStream).then(()=>{
        console.warn('本地 publish 成功')
      })
    })
  }

4. 设置直播模式

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

js  //"rtc": 通信场景,"live": 直播场景
  rtc.client.setChannelProfile({mode:'live'});

5. 加入房间

加入房间前,请确保已完成初始化相关事项。若您的业务中涉及呼叫邀请等机制,可以使用信令

自 2021年 7 月 13 日开始,初始化之前无需通过 setParameters 打开推流开关。加入房间并创建推流任务后,房间中所有成员的音视频流均可以进行混流并推流至 CDN。

js//加入房间
rtc.client.join({
    channelName: '房间名称',
    uid: uid, 
    token: token,
    joinChannelLiveConfig:{
        liveEnable:true 
    }
}).then((obj) => {
    console.info('加入房间成功...')
    //初始化本地流,并且发布
    initLocalStream() //后面介绍说明
})

参数说明

参数 说明
token 安全认证签名(NERTC Token)。可设置为:
  • null。调试模式下可设置为 null。安全性不高,建议在产品正式上线前在云信控制台中将指定应用的鉴权方式恢复为默认的安全模式。
  • 已获取的NERTC Token。安全模式下必须设置为获取到的 Token 。若未传入正确的 Token 将无法进入房间。

    推荐使用安全模式。

channelName 房间名称,设置相同房间名称的用户会进入同一个通话房间。
**注意**:您也可以在加入通道前,通过创建房间接口创建房间。加入房间时,若传入的 {channelName} 未事先创建,则云信服务器内部将为其自动创建一个名为 {channelName} 的通话房间。
uid 用户的唯一标识 id,房间内每个用户的 uid 必须是唯一的。
joinChannelLiveConfig 互动直播相关参数。通过 liveEnable 参数设置开启推流开关。

6. 推流任务管理

在成功加入房间后,需要设置推流任务将通话房间内的多媒体数据推至CDN。在典型的业务场景中,由主播设置推流任务。推流任务也可以通过 服务端API 进行管理,请根据您的业务需求选择合适的方式。

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

增加推流任务

音视频房间中默认没有推流任务,您需要在启动直播前通过 addTasks方法增加推流任务。

示例代码(增加推流任务)
js  // 示例
  // 互动直播的推流任务,可以设置多个推流任务
  let rtmpTasks = []
  // taskID 可选字母、数字,下划线,不超过64位
  let taskId = 'taskId_1' 
  // 设置推互动直播推流地址,一个推流任务对应一个推流房间
  let streamUrl = 'rtmp://xxxxxx-1' 
  // 设置是否进行互动直播录制,请注意与音视频通话录制区分。
  let record = true


  let task1 = {
            taskId,
            streamUrl,
            record,
            config: {},
            // 整体布局参数
            layout: {
                  canvas: { 
                      //整体布局宽度
                      width: 1280, 
                      //整体布局高度
                      height: 720, 
                      //整体布局背景色(转为10进制的数,如:#FFFFFF 16进制转为10进制为 16777215)
                      color: 16777215 
                  },
                  users: [{
                      uid: 100, //用户id
                      x: 0, // user1 的视频布局x偏移,相对整体布局的左上角(前提是推流发布user1的视频)
                      y: 0, // user1 的视频布局y偏移,相对整体布局的左上角(前提是推流发布user1的视频)
                      width: 640, // user1 的视频布局宽度(前提是推流发布user1的视频)
                      height: 360, //user1 的视频布局高度(前提是推流发布user1的视频)
                      adaption: 1, //自适应,值默认为1
                      pushAudio: true, // 推流是否发布user1 的音频
                      pushVideo: true // 推流是否发布user1的视频
                  },
                  {
                      uid: 200, //用户id
                      x: 0, // user2 的视频布局x偏移,相对整体布局的左上角(前提是推流发布user2的视频)
                      y: 0, // user2 的视频布局y偏移,相对整体布局的左上角(前提是推流发布user2的视频)
                      width: 640, // user2 的视频布局宽度(前提是推流发布user2的视频)
                      height: 360, //user2 的视频布局高度(前提是推流发布user2的视频)
                      adaption: 1, //自适应,值默认为1
                      pushAudio: true, // 推流是否发布user2 的音频
                      pushVideo: true // 推流是否发布user2 的视频
                  }],
                  images: [{
                      url: "xxxxxx", //设置背景图片
                      x: 0, // 背景图片x偏移,相对整体布局的左上角
                      y: 0, // 背景图片y偏移,相对整体布局的左上角
                      width: 480, // 背景图片宽度
                      height: 360,  //背景图片高度
                      adaption: 1 //自适应,值默认为1
                  }]
            }
  }
  rtmpTasks.push(task1)

  // 添加推流任务
  rtc.client.addTasks({rtmpTasks}).then(()=>{
    console.log('添加推流任务接口成功')
  }).catch(error=>{
    console.warn('添加推流任务接口失败: ', error)
    if (error == 'INVALID_PARAMETER') {
      console.log('参数错误')
    }
  })

更新推流任务

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

示例代码(更新推流任务)
js  // 示例
  // 传入新的推流任务对象。注意:其中的taskId为原推流任务taskId。
  rtmpTasks.push(newTask1)

  rtc.client.updateTasks({rtmpTasks}).then(()=>{
    console.log('更新推流任务接口调用成功')
  }).catch(error=>{
    console.warn('更新推流任务接口调用失败: ', error)
    if (error == 'INVALID_PARAMETER') {
      console.log('参数错误')
  }
  })

删除推流任务

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

示例代码(删除推流任务)
js  // 示例
  // 传入需要删除的推流任务的taskId
  let  taskIds = []
  taskIds.push('taskId_1')
  taskIds.push('taskId_2')

  rtc.client.deleteTasks({
    taskIds
  }).then(()=>{
    console.log('删除推流任务接口调用成功')
  }).catch(error=>{
    console.warn('删除推流任务接口调用失败: ', error)
    if (error == 'INVALID_PARAMETER') {
      console.log('参数错误')
    }
  })

互动直播推流状态

主播/连麦者参与互动直播的过程中,可以通过 rtmp-state 来监听推流状态。

示例代码(监听推流状态)
js  // 监听推流任务的状态
  rtc.client.on('rtmp-state', data => {
          console.warn('=====互动直播状况:', data)
          console.warn(`互动直播推流任务:${data.task_id},的结果:${data.code}`)
          if (data.code === 505) {
                  console.warn('该推流任务正在推流中,状态正常')
          } else if (data.code === 506) {
                  console.warn('该推流任务推流失败了')
          } else if (data.code === 511) {
                  console.warn('该推流任务推流结束了')
          }    
  })       

7. 设置远端视图

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

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

    • peer-online:监听远端用户加入通话房间的事件,并抛出对方的 uid。当本端加入房间后,也会通过此回调抛出通话房间内已有的其他用户。

    • stream-added:监听远端用户发布视频流的事件,回调中携带对方的 uid 与发布的视频分辨率。

  2. 在监听到远端用户发布视频流后,本方可以通过 subscribe 方法对其发起视频流的订阅,来将对方的视频流渲染到视频画布上。

    js  // 示例
      //设置要订阅音频或者视频
      remoteStream.setSubscribeConfig({
        audio: true,//订阅麦克风音频
        audioSlave: true,//订阅音频辅流
        video: true,//订阅视频
        screenShare: true,//订阅屏幕共享
        highOrLow: NERTC.STREAM_TYPE.HIGH,//订阅大流
      })
      // 发起订阅
      rtc.client.subscribe(remoteStream).then(()=>{
        console.log('发起订阅对端成功')
      })
    
  3. 订阅成功后,可进一步在 stream-subscribed 回调中播放远端视频流。

    js//播放订阅的对端的音视频流
      rtc.client.on('stream-subscribed', evt => {
        console.warn('订阅别人的流成功的通知')
        var remoteStream = evt.stream;
        let div = document.getElementById('remote-container')
        //开始播放远端音视频流
        remoteStream.play(div).then(()=>{
          console.log('播放对端的流成功')
          remoteStream.setRemoteRenderMode({
            width: 180,
            height: 150,
            cut: true
          })
        })
      })
    

观众进行 CDN 拉流

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

连麦者上下麦

1. 上麦

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

注意

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

2. 下麦

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

通话房间内的其他用户可以通过 peer-leave 来监听其他连麦者下麦。

结束互动直播

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

1. 退出通话房间

通过 leave() 接口退出通话房间。

js  //用户无需做一些清除动作,sdk会自动做清除逻辑
  rtc.client.leave()

2. 销毁实例

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

js  //一般情况下无需使用
  rtc.client.destroy()
此文档是否对你有帮助?
有帮助
去反馈
  • 前提条件
  • 主播加入房间
  • 1. 引用文件
  • 2. 初始化
  • 3. 设置本地视图(可选)
  • 4. 设置直播模式
  • 5. 加入房间
  • 6. 推流任务管理
  • 增加推流任务
  • 更新推流任务
  • 删除推流任务
  • 互动直播推流状态
  • 7. 设置远端视图
  • 观众进行 CDN 拉流
  • 连麦者上下麦
  • 1. 上麦
  • 2. 下麦
  • 结束互动直播
  • 1. 退出通话房间
  • 2. 销毁实例