旁路推流

更新时间: 2024/08/05 15:02:55

NERTC SDK 支持云端音视频混流和 RTMP 旁路推流,可以将实时音视频流转为标准直播流,并将其从网易云信实时音视频云推送到第三方 CDN(Content Delivery Network)或网易云信直播服务。

推流到 CDN 后,基于 CDN 的大规模内容分发,观众可通过 URL 拉流地址使用播放器或 Web 端浏览器直接在线观看直播,也可以加入音视频房间进行实时连麦。当房间中有多个主播时,需要将多个直播流组合成单流,并设置直播流的推流布局,在直播画布中显示主播们的实时画面。

您可以选择通过客户端或者服务端实现旁路推流,服务端推流方法请参考旁路推流。移动客户端受限于网络状况,为保证直播的稳定性,建议通过服务端实现旁路推流。本文档为您展示通过客户端进行旁路推流的实现方式。

功能介绍

在您的项目中实现音视频通话后,可以将房间画面进行旁路推流。网易云信可以将您的媒体流在云端进行混流、转码、合图等操作,生成一路视频流,并将其推送到网易云信直播服务中进行大规模内容分发,以便观众直播观看。

  • 房间内首个终端加入自动触发转码,房间内无终端时停止转码。
  • 直播流支持 RTMP 协议。

前提条件

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

注意事项

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

配置步骤

步骤一 调用 addTasks 方法,创建推流任务

调用此方法时,您需要配置任务 ID、推流地址等推流任务的参数信息,还可以选择是否开启直播视频录制。

录制的视频默认存储在点播服务中,您可以通过点播的相关接口查看并下载视频文件。详细信息请参考点播媒资管理。

相关参数的描述如下表。

参数名称 参数描述
taskId 自定义的推流任务 ID。请保证此 ID 唯一,且 ID 为字母数字下划线组成的 64 位以内的字符串。
streamUrl 推流地址,例如 rtmp://test.url。 此推流地址可设置为网易云信直播产品中服务端 API 创建直播频道的返回参数 pushUrl。
record 旁路推流是否需要进行音视频录制。

layout

设置互动直播的画面布局,例如调整画布大小和颜色、各路视频的图像大小、位置等。

config 配置音视频流编码参数等。
extraInfo 额外的配置信息。

config 参数用于配置音视频流编码参数以及设置是否透传。

  • 通过 audioParam 设置音频编码参数。
    • 通过 bitRate 设置音频推流码率。单位为 kbps,取值范围为 10~192。语音场景建议设置为 64 及以上码率,音乐场景建议设置为 128 及以上码率。
    • 通过 channels 设置音频推流声道数,默认值为 2,即双声道。
    • 通过 codecProfile 设置音频编码规格。默认为 LC-AAC 规格,相关枚举值如下。
      • NERTC.LIVE_STREAM_AUDIO_CODEC_PROFILE.LC_AAC,即 LC-AAC 规格,表示基本音频编码规格,
      • NERTC.LIVE_STREAM_AUDIO_CODEC_PROFILE.HE_AAC: 表示高效音频编码规格
    • 通过 sampleRate 设置音频推流采样率。默认值为 48 kHZ,相关枚举值如下。
      • NERTC.LIVE_STREAM_AUDIO_SAMPLE_RATE.SAMPLE_RATE_32000 : 32000
      • NERTC.LIVE_STREAM_AUDIO_SAMPLE_RATE.SAMPLE_RATE_44100 : 44100
      • NERTC.LIVE_STREAM_AUDIO_SAMPLE_RATE.SAMPLE_RATE_48000 : 48000(默认)
  • 通过 singleVideoNoTrans 设置视频透传。singleVideoNoTrans 参数设置为 true 表示开启视频透传,开启后,如果房间中只有一路视频流输入,则不对输入视频流进行转码,不遵循转码布局,直接推流 CDN。视频透传默认为关闭状态。

示例代码

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


  let task1 = {
            taskId,
            streamUrl,
            record,
            // 整体布局参数
            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 方法,更新推流任务

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

示例代码

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

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

步骤三 监听互动直播推流任务状态

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

示例代码

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

步骤四 调用 deleteTasks 方法,删除推流任务

当本场互动直播准备结束时,您可以调用 deleteTasks 主动删除推流任务。

示例代码

  // 传入需要删除的推流任务的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('参数错误')
    }
  })

API 参考

方法 功能描述
addTasks 创建推流任务
updateTasks 更新推流任务
deleteTasks 删除推流任务

常见问题

我将角色从观众切换至连麦者时,为什么会听到主播声音的回声?

答:在您切换角色至连麦者时,实际上是从通过播放器拉流切换至加入 RTC 房间订阅主播的媒体流。听到回声的原因是您在连麦成功后,未释放播放器播放实例相关资源,而直接加入了音视频房间并订阅主播音视频流,致使主播媒体流同时从播放器以及在音视频房间中播放。

网易云信建议您在互动直播中,实现连麦者上麦的标准步骤:

  1. 连麦成功。

  2. 退出播放,调用 release 方法释放播放器实例和资源。

  3. 初始化音视频通话 SDK 并进入音视频房间。

  4. 订阅远端音视频流。

为什么推流端推流后,拉流端有时候拉不到流?

答:原因可能是您调用 publish 方法在 RTC 房间里发流和调用 addTasks 或 updateTasks 方法进行旁路推流的时序错误,或者没有成功订阅远端用户的流后就进行混流转推,导致互动直播混流并转推时缺少相应的数据源。

请在推旁路流之前确保对应的流已在 RTC 房间发布成功,所以您需要在调用 publish 方法成功发流之后再调用 addTasks 或 updateTasks方法;如果您还想转推 RTC 房间内其他用户发布的流,请在收到对应用户的 stream-added/stream-subscribed 回调之后再调用 addTasks 或者 updateTasks 方法。

此文档是否对你有帮助?
有帮助
去反馈
  • 功能介绍
  • 前提条件
  • 注意事项
  • 配置步骤
  • 步骤一 调用 addTasks 方法,创建推流任务
  • 示例代码
  • 步骤二 调用 updateTasks 方法,更新推流任务
  • 示例代码
  • 步骤三 监听互动直播推流任务状态
  • 示例代码
  • 步骤四 调用 deleteTasks 方法,删除推流任务
  • 示例代码
  • API 参考
  • 常见问题
  • 我将角色从观众切换至连麦者时,为什么会听到主播声音的回声?
  • 为什么推流端推流后,拉流端有时候拉不到流?