旁路推流画面布局
更新时间: 2024/08/05 15:02:55
配置旁路推流任务时,您可以自定义房间画面的各路视频布局方式,例如调整整体画布大小和颜色、各路视频的图像大小、位置等。本文档为您介绍视频布局的设置方式和推荐设置。
限制说明
- 用户窗口边界不能超出整体画布。
- 视频互动的画面布局中,最多 7 人参与;纯语音互动最多 21 人。
设置画面布局
您可以选择通过客户端的旁路推流相关接口的 layout
参数或者服务端 RESTful API 设置旁路推流的画面布局,服务端设置旁路推流画面布局的方法请参考旁路推流画面布局。移动客户端受限于网络状况,为保证直播的稳定性,建议通过服务端实现旁路推流。本文档为您展示通过客户端设置旁路推流画面布局的实现方式。
背景画布
通过 NERtcLiveStreamLayout
类的 width
等字段设置混流视频的背景画布属性,包括背景画布的高度、宽度和颜色。
相关字段的具体说明如下:
参数名称 |
类型 |
描述 |
---|---|---|
width | NSInteger | 整体画布的宽度,单位为 px。 取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。 |
height | NSInteger | 整体画布的高度,单位为 px。 取值范围为 0 ~ 1920。若设置为奇数值,会自动向下取偶。 |
backgroundColor |
NSUInteger |
画面背景颜色,默认为 0,即黑色。支持以下格式的颜色码:
|
用户画面
通过 NERtcLiveStreamLayout
类的 userTranscodingList
参数设置混流视频中每个参与者对应的画面属性。
参数名称 |
类型 |
描述 |
---|---|---|
uid | uint64_t | 将指定 uid 对应用户的视频流拉入直播。 如果添加多个 users,则 uid 不能重复。 |
videoPush |
BOOL |
是否在直播中向观看者播放该用户的对应视频流。可设置为:
|
audioPush |
BOOL |
是否在直播中混流该用户的对应音频流。可设置为:
|
x | NSInteger | 通过 x 和 y 指定画布坐标中的一个点,该点将作为用户图像的左上角。 x 参数用于设置画布的横轴坐标值。 取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。 |
y | NSInteger | 通过 x 和 y 指定画布坐标中的一个点,该点将作为用户图像的左上角。 y 参数用于设置画布的纵轴坐标值。 取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。 |
width | NSInteger | 该用户图像在画布中的宽度。 取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。 |
height | NSInteger | 该用户图像在画布中的高度。 取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。 |
zOrder |
NSInteger |
直播视频上用户视频帧的图层编号。取值范围为 0 ~ 100。
|
adaption |
NSInteger |
用于设置视频画面和指定区域的适应属性。可设置为:
|
占位图片
通过 NERtcLiveStreamLayout
类的 bgImgs
参数设置混流视频中的占位图片属性,包括占位图片的位置、URL 等。
- 支持设置最多 6 张图片。
- 您可以通过
NERtcLiveConfig
的interruptedPlaceImage
字段选择是否开启此功能;若设置为关闭,则此设置无效。 - 原
bgImg
字段仍保留,仅可设置一张占位图,若您同时配置了两个字段,则以bgImgs
配置为准。
参数名称 | 类型 | 描述 |
---|---|---|
url | NSString | 占位图片的 URL。 |
x | NSInteger | 通过 x 和 y 指定画布坐标中的一个点,该点将作为占位图片的左上角。 x 参数用于设置画布的横轴坐标值。 取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。 |
y | NSInteger | 通过 x 和 y 指定画布坐标中的一个点,该点将作为占位图片的左上角。 y 参数用于设置画布的纵轴坐标值。 取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。 |
width | NSInteger | 该占位图片在画布中的宽度。 取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。 |
height | NSInteger | 该占位图片在画布中的高度。 取值范围为 0 ~ 1920,若设置为奇数值,会自动向下取偶。 |
zOrder |
NSInteger |
直播视频上用户视频帧的图层编号。取值范围为 0 ~ 100。
|
布局示例
本节为您介绍如何通过客户端 addLiveStreamTask
接口的 layout
参数设置旁路推流画面布局。
请求示例
在本示例中,音视频房间中有两位主播/连麦者,其推流画面布局为横向左右均分布局,原始画布为深灰色,其中一人掉线后显示占位图片。
示例代码如下:
objc// 加入房间前设置直播模式。
[NERtcEngine.sharedEngine setChannelProfile:kNERtcChannelProfileLiveBroadcasting];
//加入房间后添加推流任务
NERtcLiveStreamTaskInfo *info = [[NERtcLiveStreamTaskInfo alloc] init];
info.taskID = 123;
info.streamURL = rtmp://test.url;
info.serverRecordEnabled = NO;
info.lsMode = kNERtcLsModeVideo;
//设置整体布局
NERtcLiveStreamLayout *layout = [[NERtcLiveStreamLayout alloc] init];
layout.width = 720;
layout.height = 640;
layout.backgroundColor = #8421504;
info.layout = layout;
//设置左边成员布局
NERtcLiveStreamUserTranscoding *user1 = [[NERtcLiveStreamUserTranscoding alloc] init];
user1.uid = 66601;
user1.audioPush = true;
user1.videoPush = enableVideo;
if (user1.videoPush) {
user1.x = 0;
user1.y = 0;
user1.width = 360;
user1.height = 640;
user1.adaption = kNERtcLsModeVideoScaleCropFill;
user1.zOrder = 1;
}
//设置右边成员布局
NERtcLiveStreamUserTranscoding *user2 = [[NERtcLiveStreamUserTranscoding alloc]init];
user2.uid = 66602;
user2.audioPush = true;
user2.videoPush = enableVideo;
if (user2.videoPush) {
user2.x = 360;
user2.y = 0;
user2.width = 360;
user2.height = 640;
user2.adaption = kNERtcLsModeVideoScaleCropFill;
user2.zOrder = 1;
}
layout.users = @[user1,user2];
//设置音视频流编码参数
NERtcLiveConfig *config = [[NERtcLiveConfig alloc] init];
config.interruptedPlaceImage = true;
config.singleVideoPassthrough = true;
config.audioBitrate = 64 kbps;
config.sampleRate = kNERtcLiveStreamAudioSampleRate48000;
config.audioCodecProfile= kNERtcLiveStreamAudioCodecProfileLCAAC;
config.channels = 2;
layout.config = config;
//设置占位图片布局
NERtcLiveStreamImageInfo *image1 = [[NERtcLiveStreamImageInfo alloc] init];
image1.url = www.163.com/test.jpg;
image1.x = 360;
image1.y = 0;
image1.width = 360;
image1.height = 640;
image.zOrder = 0;
layout.bgImages = @[image1];
//调用 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(@"调用添加推流任务失败");
}
效果展示
-
原始画布:
-
增加占位图片:
-
正常显示画面:
-
右侧用户断线:
-
左侧用户断线:
常用布局设置
互动直播支持自定义配置视频布局,您也可以参考以下典型的常用布局配置,优化您的自定义布局。
双人横向平铺
-
显示效果
-
layout
参数配置示例
//设置整体布局
NERtcLiveStreamLayout *layout = [[NERtcLiveStreamLayout alloc] init];
layout.width = 640;
layout.height = 360;
layout.backgroundColor = #16777215;
info.layout = layout;
//设置左边成员布局
NERtcLiveStreamUserTranscoding *user1 = [[NERtcLiveStreamUserTranscoding alloc] init];
user1.uid = 66601;
user1.audioPush = true;
user1.videoPush = enableVideo;
if (user1.videoPush) {
user1.x = 0;
user1.y = 0;
user1.width = 320;
user1.height = 360;
user1.adaption = kNERtcLsModeVideoScaleCropFill;
user1.zOrder = 1;
}
//设置右边成员布局
NERtcLiveStreamUserTranscoding *user2 = [[NERtcLiveStreamUserTranscoding alloc]init];
user2.uid = 66602;
user2.audioPush = true;
user2.videoPush = enableVideo;
if (user2.videoPush) {
user2.x = 320;
user2.y = 0;
user2.width = 320;
user2.height = 360;
user2.adaption = kNERtcLsModeVideoScaleCropFill;
user2.zOrder = 1;
}
layout.users = @[user1,user2];
三人纵向平铺
-
显示效果
-
layout
参数配置示例
//设置整体布局
NERtcLiveStreamLayout *layout = [[NERtcLiveStreamLayout alloc] init];
layout.width = 360;
layout.height = 640;
layout.backgroundColor = #16777215;
info.layout = layout;
//设置上方成员布局
NERtcLiveStreamUserTranscoding *user1 = [[NERtcLiveStreamUserTranscoding alloc] init];
user1.uid = 123;
user1.audioPush = true;
user1.videoPush = enableVideo;
if (user1.videoPush) {
user1.x = 0;
user1.y = 0;
user1.width = 360;
user1.height = 320;
user1.adaption = kNERtcLsModeVideoScaleCropFill;
user1.zOrder = 1;
}
//设置左下成员布局
NERtcLiveStreamUserTranscoding *user2 = [[NERtcLiveStreamUserTranscoding alloc]init];
user2.uid = 456;
user2.audioPush = true;
user2.videoPush = enableVideo;
if (user2.videoPush) {
user2.x = 0;
user2.y = 320;
user2.width = 180;
user2.height = 320;
user2.adaption = kNERtcLsModeVideoScaleCropFill;
user2.zOrder = 1;
}
//设置右下成员布局
NERtcLiveStreamUserTranscoding *user3 = [[NERtcLiveStreamUserTranscoding alloc]init];
user3.uid = 789;
user3.audioPush = true;
user3.videoPush = enableVideo;
if (user3.videoPush) {
user3.x = 180;
user3.y = 320;
user3.width = 180;
user3.height = 320;
user3.adaption = kNERtcLsModeVideoScaleCropFill;
user3.zOrder = 1;
}
layout.users = @[user1,user2,user3];
1 + N 悬浮布局
-
显示效果
-
layout
参数配置示例
//设置整体布局
NERtcLiveStreamLayout *layout = [[NERtcLiveStreamLayout alloc] init];
layout.width = 360;
layout.height = 640;
layout.backgroundColor = #16777215;
info.layout = layout;
//设置上方成员布局
NERtcLiveStreamUserTranscoding *user1 = [[NERtcLiveStreamUserTranscoding alloc] init];
user1.uid = 123;
user1.audioPush = true;
user1.videoPush = enableVideo;
if (user1.videoPush) {
user1.x = 0;
user1.y = 0;
user1.width = 360;
user1.height = 640;
user1.adaption = kNERtcLsModeVideoScaleCropFill;
user1.zOrder = 1;
}
//设置左下成员布局
NERtcLiveStreamUserTranscoding *user2 = [[NERtcLiveStreamUserTranscoding alloc]init];
user2.uid = 456;
user2.audioPush = true;
user2.videoPush = enableVideo;
if (user2.videoPush) {
user2.x = 45;
user2.y = 390;
user2.width = 110;
user2.height = 213;
user2.adaption = kNERtcLsModeVideoScaleCropFill;
user2.zOrder = 1;
}
//设置右下成员布局
NERtcLiveStreamUserTranscoding *user3 = [[NERtcLiveStreamUserTranscoding alloc]init];
user3.uid = 789;
user3.audioPush = true;
user3.videoPush = enableVideo;
if (user3.videoPush) {
user3.x = 185;
user3.y = 390;
user3.width = 110;
user3.height = 213;
user3.adaption = kNERtcLsModeVideoScaleCropFill;
user3.zOrder = 1;
}
layout.users = @[user1,user2,user3];