旁路推流

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

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

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

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

功能描述

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

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

前提条件

  • 主播端推流之前,需要通过 setChannelProfile 接口设置房间模式为直播模式。
  • 发起推流任务之前,请确认您已实现音视频通话的相关流程。详细信息请参考接入流程

注意事项

  • 同一个音视频房间(即同一个 channelId)可以创建 6 个不同的推流任务。
  • 客户端 SDK 添加推流任务时,默认将创建推流任务的用户 UID 设置为主播角色。互动直播场景中,仅支持解析主播端的 SEI 自定义数据。
  • 自 V4.4.0 版本起,初始化之前无需通过 setParameters 接口打开推流开关。加入房间并创建推流任务后,房间中所有成员的音视频流均可以进行混流并推流至 CDN。
  • 移动客户端互动直播受限于网络状况,为保证直播的稳定性,推荐通过服务端实现旁路推流

实现方式

在项目中实现音视频通话后,可以调用 addLiveStreamTask 接口创建推流任务,并配置推流画面布局,将房间画面进行旁路推流。

其中参数 taskInfo 用于设置推流任务信息,包括任务基本信息、推流布局、 音视频流配置等。

配置推流任务信息

创建推流任务时,需要配置任务 ID、推流地址等推流参数信息,还可以开启直播视频录制。

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

推流任务信息相关参数说明如下:

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

ls_mode

直播推流模式。可设置为:

  • kNERtcLsModeAudio:推流纯音频。
  • kNERtcLsModeVideo:推流音视频。

配置推流布局

通过 layout 参数可以设置互动直播的画面布局,即自定义房间画面的各路视频布局方式,例如调整整体画布大小和颜色、各路视频的图像大小、位置等。

布局参数的配置方式及典型配置示例请参考旁路推流画面布局

推流布局相关参数说明如下:

参数名称 描述
width 整体画布的宽度,单位为 px。
取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。整体画布的高度与宽度的乘积不得大于 1920*1080。
height 整体画布的高度,单位为 px。
取值范围为 0 ~ 1920。若设置为奇数值,会自动向下取偶。整体画布的高度与宽度的乘积不得大于 1920*1080。

background_color

画面背景颜色,默认为 0,即黑色。支持以下格式的颜色码:

  • 256 ✖ 256 ✖ R + 256 ✖ G + B 的和。请将对应 RGB 的值分别带入此公式计算即可。
  • 十六进制颜色码,即#RRGGBB 或 RRGGBB 格式。例如 #CC00FF。
bg_image_count 占位图布局个数。
bg_image 占位图片数组。字段相关具体说明请参考 NERtcLiveStreamImageInfo
  • 支持设置最多 6 张图片。
  • 您可以通过 NERtcLiveConfiginterrupted_place_image 字段选择是否开启此功能;若设置为关闭,则此设置无效。
user_count 成员布局个数。
users 成员布局数组。字段相关具体说明请参考 NERtcLiveStreamUserTranscoding

音视频流配置

config 参数用于配置音视频流编码参数等设置。

参数名称 描述
interrupted_place_image 参数设置为 true 表示开启主播占位图模式,开启后,通过 layoutbg_image 字段设置的占位图列表才可生效。
single_video_passthrough 参数设置为 true 表示开启视频透传,开启后,如果房间中只有一路视频流输入,则不对输入视频流进行转码,不遵循转码布局,直接推流 CDN。视频透传默认为关闭状态。
audio_bitrate 音频推流码率。单位为 kbps,取值范围为 10 ~ 192。语音场景建议设置为 64 及以上码率,音乐场景建议设置为 128 及以上码率。
sampleRate 音频推流采样率。默认值为 kNERtcLiveStreamAudioSampleRate48000,即 48K。
channels 音频推流声道数,默认为 2,即双声道。
audioCodecProfile 音频编码规格,默认为 0,即 LC-AAC 规格,表示基本音频编码规格。

API 参考

方法
功能
addLiveStreamTask 添加房间推流任务。
updateLiveStreamTask 更新修改房间推流任务。
removeLiveStreamTask 删除房间推流任务。

事件
描述
onAddLiveStreamTask 通知添加直播任务结果。
onUpdateLiveStreamTask 通知更新直播任务结果。
onRemoveLiveStreamTask 通知删除直播任务结果。
onLiveStreamState 通知直播推流状态。

示例代码

C++//加入房间前设置直播模式
//kNERtcChannelProfileCommunication为通话模式
//kNERtcChannelProfileLiveBroadcasting为直播模式
NERtcChannelProfileType channelProfileType = kNERtcChannelProfileLiveBroadcasting;
rtc_engine_->setChannelProfile(channelProfileType);

// 加入房间后创建推流任务
// 添加推流任务的异步callback,更多错误码请参考onAddLiveStreamTask的API文档
void onAddLiveStreamTask(const char* task_id, const char* url, int error_code){
    if (code == kNERtcNoError) {
        showToast("添加推流任务成功 : taskId " + taskId);
    } else {
        showToast("添加推流任务失败 : taskId " + taskId + " , code : " + code);
    }
};

//推流任务数据结构
NERtcLiveStreamTaskInfo ls_task_info_;
//请务必保证一个URL地址只能设置一个推流任务,请使用上层自己维护的task_id、url
strncpy(ls_task_info_.task_id, task_id.c_str(), kNERtcMaxTaskIDLength);
strncpy(ls_task_info_.stream_url, url.c_str(), kNERtcMaxURILength);
ls_task_info_.ls_mode = kNERtcLsModeVideo;
ls_task_info_.server_record_enabled = false;

//设置音视频编码参数
ls_task_info_.config.interrupted_place_image = false;//设置是否开启推流成员离线时的占位图
ls_task_info_.config.single_video_passthrough = false;//设置是否开启单路视频透传开关
ls_task_info_.config.audio_bitrate = 192;//设置音频推流码率
ls_task_info_.config.sampleRate = kNERtcLiveStreamAudioSampleRate48000;//设置音频推流采样率
ls_task_info_.config.audioCodecProfile = NERtcLiveStreamAudioCodecProfileLCAAC;//设置音频编码规格
ls_task_info_.config.channels = 2;//设置音频推流声道数

//设置整体布局
ls_task_info_.layout.background_color = 0x3399ff; // 整体背景色
ls_task_info_.layout.width = 1280;//整体布局宽度
ls_task_info_.layout.height = 640;//整体布局高度

//设置直播成员布局
ls_task_info_.layout.user_count = 2;
ls_task_info_.layout.users = new NERtcLiveStreamUserTranscoding[2];
ls_task_info_.layout.users[0].uid = uid;
ls_task_info_.layout.users[1].uid = remote_uid;
for (int i = 0; i < ls_task_info_.layout.user_count; i++)
{
    ls_task_info_.layout.users[i].adaption = kNERtcLsModeVideoScaleFit;
    ls_task_info_.layout.users[i].video_push = true;// 推流是否发布user的视频
    ls_task_info_.layout.users[i].x = 640 * i;      // user 的视频布局x偏移,相对整体布局的左上角
    ls_task_info_.layout.users[i].y = 0;            // user 的视频布局y偏移,相对整体布局的左上角
    ls_task_info_.layout.users[i].width = 640;      // user 的视频布局宽度
    ls_task_info_.layout.users[i].height = 640;     //user 的视频布局高度
    ls_task_info_.layout.users[i].audio_push = true;// 推流是否发布user的音频
    ls_task_info_.layout.users[i].zorder = 1;// user 的视频帧的图层编号
}

//设置占位图布局
ls_task_info_.layout.bg_image_count = 2;
ls_task_info_.layout.bg_image       = new NERtcLiveStreamImageInfo[2];
memset(ls_task_info_.layout.bg_image, 0, sizeof(NERtcLiveStreamImageInfo) * 2);
for (int i = 0; i < 2; i++)
{
    memcpy(ls_task_info_.layout.bg_image[i].url, url.data(), url.size());
    ls_task_info_.layout.bg_image[i].x = 0 + 640 * i;
    ls_task_info_.layout.bg_image[i].y = 0;
    ls_task_info_.layout.bg_image[i].width = 640;
    ls_task_info_.layout.bg_image[i].height = 480;
    ls_task_info_.layout.bg_image[i].zorder = 0;
}

// 如果需要,可以配置多个用户,配置的用户不用已经在房间中,如果用户不在房间中,那么会有相应的视频占位
// 之后用户以配置了的uid进入房间,开启推流开关即可推流
int ret = addLiveStreamTask(ls_task_info_);
if (ret != 0) {
    showToast("调用添加推流任务失败 , ret : " + ret);
}

常见问题

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

此文档是否对你有帮助?
有帮助
去反馈
  • 功能描述
  • 前提条件
  • 注意事项
  • 实现方式
  • 配置推流任务信息
  • 配置推流布局
  • 音视频流配置
  • API 参考
  • 示例代码
  • 常见问题