布局参数说明
在使用RESTful API开启云端录制和CDN推流时都有一个layout
参数,用于设置视频合流布局。
本文对该参数进行详细说明。
布局参数
{
"mode": <int>, // 必须,布局模式
"scale": <int>, // 必须,缩放模式
"canvas": { // 必须,画布背景
"width": 1280,
"height": 720,
"color": "#000000" // RGB
},
"activeVideo": <bool> // 可选,自动激活视频
}
参数说明:
如果参数配置错误,或者必须参数缺失,服务器将采用默认布局。
- mode - 值为int,用于表示布局模式,Pano有3种预设布局,也支持客户自定义布局:
- mode = 0,画廊模式(Gallery),即两分格、四分格、九宫格等
- mode = 1,悬浮模式(Floating),主画面全屏,小画面横排或竖排悬浮在主画面上
- mode = 2,演讲者模式(Speaker),主画面大图,小画面横排或竖排在画布侧面,与主画面不重叠
- mode = 3,自定义布局(Custom)
- scale - 值为int,表示缩放模式:
- scale = 0,aspectFit,保持原有长宽比缩放,画面显示在目标区域中间
- scale = 1,aspectFill,保持原有长宽比缩放,填满目标区域,超出部分会被截断
- scale = 2,fill,缩放画面,将其完整显示在目标区域,但是画面可能会被拉伸(长宽比改变)
- canvas - 背景画布大小与底色
- 画布最大为1920x1080(或1080x1920),超过的话Pano会使用1920x1080(或1080x1920)作为画布大小
- 当 width > height 时,表示横屏画面(例如:1280x720、1920x1080);当 width < height 时,表示竖屏画面(例如:720x1280、1080x1920)
- activeVideo - 值为bool(默认为false),用于预设布局模式,表示是否将频道中音量最大者的视频自动显示在主画面(1号位)
注意:如果频道同时开启屏幕共享或白板,他们的优先级比视频更高,即使activeVideo设置为true,屏幕共享或白板也会优先填充到主画面
预设布局
画廊模式
参数示例:
{
"mode": 0,
"scale": <int>,
"canvas": {
"width": 1280,
"height": 720,
"color": "#000000"
}
}
效果示意图:
说明:
- 纯音频参与者不占位。
- 竖屏最多支持9画面,横屏最多支持16画面,超过的画面不显示。
- 如果画面数不足以充满某一档位,则剩余的位置留空。例如,竖屏7画面,则8、9号位留空。
悬浮模式
参数示例:
{
"mode": 1,
"scale": <int>,
"canvas": {
"width": 1280,
"height": 720,
"color": "#000000"
}
}
效果示意图:
说明:
- 纯音频参与者不占位。
- 1号位主画面始终全屏显示(画面数大于1时,主画面会被部分覆盖)。
- 竖屏最多支持9画面,横屏最多支持17画面,超过的画面不显示。
- 如果画面数不足以充满某一档位,则剩余的位置留空。例如,竖屏7画面,则8、9号位留空。
- 小画面尺寸:
- 竖屏双画面:小画面的宽高是画布的1/3
- 竖屏3-4画面:小画面的宽高是画布的1/3.5,水平和垂直间距是画布宽高的1/28
- 竖屏5-9画面:小画面的宽高是画布的1/4
- 横屏画面:小画面的宽高是画布的1/4.25,水平和垂直间距是画布宽高的1/85
演讲者模式
演讲者模式适用于横屏,主画面和小画面横向或纵向平铺,相互不重叠,并且保持宽高比一致。
参数示例:
{
"mode": 2,
"align": <int>, // 可选,对齐方式,0-right(右侧对齐,默认值), 1-left(左侧对齐)
// 2-top(顶部对齐), 3-bottom(底部对齐)
"scale": <int>,
"canvas": {
"width": 1280,
"height": 720,
"color": "#000000"
}
}
效果示意图:
说明:
- 纯音频参与者不占位。
- 小画面不会覆盖1号位主画面(主画面显示在除小画面行列外的剩余区域)。
- 右侧/左侧对齐最多支持17画面,顶部/底部对齐最多支持8画面,超过的画面不显示。
- 右侧/左侧对齐时,如果画面数不足以充满某一档位,则剩余的位置留空。
例如,共7画面,则8、9号位留空。 - 顶部/底部对齐时,所有小画面在行内水平居中分布。
- 小画面尺寸计算公式:
- 左侧或右侧对齐时:
- width = canvas_width /(cell_num_per_col + col_num)
- height = canvas_height / (cell_num_per_col)
- 顶部或底部对齐时:
- width = canvas_width / cell_num_per_row
- height = canvas_height / (cell_num_per_row + 1)
- 其中:
- canvas_width:画布宽度
- canvas_height:画布高度
- cell_num_per_col:单列小画面数量
- col_num:小画面列数
- cell_num_per_row:单行小画面数量
- 左侧或右侧对齐时:
默认布局
layout参数为空时使用下面的默认布局:
{
"mode": 0,
"scale": 0,
"canvas": {
"width": 1280,
"height": 720,
"color": "#000000"
}
}
画面排列顺序
预设布局的画面排列顺序如下。
- 首先根据视频流类型排列,优先级:屏幕共享(Content Share) > 白板(Whiteboard) > 视频(Video)
- 在录制、推流的RESTful API参数里有一个
userId
参数表示主讲人,如果userId不为空,则userId对应的画面为主画面,否则第一个加会的人为主画面 - 如果有多个视频画面,根据对应用户的加会顺序依次排列
- 如果activeVideo参数为true,则自动激活视频
自定义布局
如果预设布局无法满足需要,可以使用自定义布局。layout参数里可包含多个小画面设置,参数示例:
{
"mode": 3,
"scale": <int>,
"canvas": {
"width": 1280,
"height": 720,
"color": "#000000"
},
"customModeCells":[
{
"userId": "123",
"streamType": 0,
"x": 0,
"y": 0,
"width": 0.5,
"height": 1,
"zOrder": 0
},
{
"sequence": 1,
"streamType": 0,
"x": 0.5,
"y": 0,
"width": 0.5,
"height": 1,
"zOrder": 0
}
]
}
上面示例代码的效果示意图如下:
参数说明:
- streamType - (可选)值为int,表示显示的视频流类型:0-视频(默认值)、1-屏幕共享、2-白板、3-任意类型,可以显示视频、屏幕共享和白板。
- userId、sequence、whiteboardId - (三种匹配模式选其一) 通过指定用户userId、加入频道顺序或者白板ID,匹配画面待显示的用户和视频流类型
- userId 值为string,表示显示在该画面上用户的userId,结合streamType可以具体对应到用户的某个特定视频流(视频或屏幕共享)
- sequence 值为int,仅对视频有效(streamType=0)。如果在设置布局的时候,无法确定画面要显示的用户userId,可以按照用户加入频道顺序自动排列。sequence是用户加会的顺序,从1开始递增。1表示第一个加入的用户,2表示第二个加入频道的用户。
- whiteboardId 值为string,表示白板的唯一ID,画面会显示对应白板渲染后的图像。默认的白板ID为"default"。
- 单个画面不能同时设定userId、sequence和whiteboardId。多个画面可以用不同的方式显示,比如,画面1和2指定userId1和userId2,画面3和4指定sequence1和sequence2,最终画面1和2分别会显示userId1和userId2用户,画面3和4会按照其他用户加入频道顺序显示第一和第二的用户
也就是说,不同的视频流类型支持下列配置方式:
- 视频:方式一、(streamType=0)+userId的组合;方式二、按照加会顺序设置,(streamType=0)+sequence的组合。
- 屏幕共享:(streamType=1)+userId的组合
- 白板:(streamType=2)+whiteboardId的组合
- x - (必填)值为float,表示画面左上角在画布中的横坐标相对值,取值范围是[0.0, 1.0),0.0表示画布的最左端,1.0是画布的最右端
- y - (必填)值为float,表示画面左上角在画布中的纵坐标相对值,取值范围是[0.0, 1.0),0.0表示画布的最顶端,1.0是画布的最底端
- width、height - (必填)值为float,画面宽高的相对值,取值范围是(0.0, 1.0]。比如,width值是0.5,该画面的实际宽度是画布宽度的一半
- zOrder - (可选)值为int,图层堆叠顺序。如果画面有重叠,通过zOrder可设置画面堆叠的顺序。拥有更大堆叠顺序的画面会覆盖堆叠顺序较小的画面。
我们在custom_layout_samples项目,提供了一些自定义布局实现示例,用户可以参考定制自己的布局。
显示多路视频
当客户端SDK同一用户同时发送多路视频时,可以在自定义布局中组合 (streamType=0)+userId+streamId 匹配特定视频流,示例如下:
注意:此处的 streamId 是指客户端SDK的视频流ID,和服务端API的 streamList 中的 streamId 含义不同,请注意区分不要混淆。
{
"mode": 3,
"scale": <int>,
"canvas": {
"width": 1280,
"height": 720,
"color": "#000000"
},
"customModeCells":[
{
"userId": "123",
"streamType": 0,
"streamId": 1, // int, 客户端SDK的视频流streamId
"x": 0,
"y": 0,
"width": 0.5,
"height": 1,
"zOrder": 0
},
{
"userId": "123",
"streamType": 0,
"streamId": 2, // int, 客户端SDK的视频流streamId
"x": 0,
"y": 0,
"width": 0.5,
"height": 1,
"zOrder": 0
}
]
}
自定义动态布局
单个自定义布局有时无法满足特定场景需求,例如两人连麦时使用悬浮模式,三人连麦时换用演讲者模式。
一种解决方案是在场景变化时,调用推流或录制的更新接口更新布局。
Pano也提供自定义动态布局方案,开启推流或录制时提前设置多个布局,Pano服务器会根据相应的规则动态选择相应的布局。
自定义动态布局只支持按照频道内视频流数量(streamNumber
)进行匹配,开发者需要在布局参数内设置 type
参数为 1
,然后设置 layoutsByStream
数据。
layoutsByStream
中的mode
、scale
、canvas
参数含义,请参考布局参数。- 如果实际视频流数量没有对应的配置项,则会自动匹配到最接近的最大值。例如:
- 仅配置了1、2、3路视频流的布局,当实际视频流数量为 4 的时候,最接近的最大值为 3,所以会使用 3 路视频流的布局;
- 如果配置了1、2、3、5路视频流的布局,当实际视频流数量为 4 的时候,最接近的最大值为 5,所以会使用 5 路视频流的布局。
以下示例配置了 3 种布局,一路流采用画廊模式,两路流采用悬浮模式,三路流采用演讲者模式:
{
"type": 1, // 自定义动态布局
"layoutsByStream": [
{
"streamNumber": 1, // 单路流的布局
"mode": 0,
"scale": 0,
"canvas": {
"width": 1280,
"height": 720,
"color": "#000000"
}
},
{
"streamNumber": 2, // 两路流的布局
"mode": 1,
"scale": 0,
"canvas": {
"width": 1280,
"height": 720,
"color": "#000000"
}
},
{
"streamNumber": 3, // 三路流的布局
"mode": 2,
"scale": 0,
"canvas": {
"width": 1280,
"height": 720,
"color": "#000000"
}
}
]
}