通过参会者事件回调开发者可获取当前会议中的人数, 根据人数可通过调用 changeLayout 实现按需请流
/**
* 统一layout请流
* @param unityLayoutRequests
*/
changeLayout(unityLayoutRequests: Array): void;
示例代码如下:
static getSDKUnityLayoutLayoutConfigInstall(width: number, height: number): XYSDKUnityLayoutLayoutConfig {
let config: XYSDKUnityLayoutLayoutConfig = {} as XYSDKUnityLayoutLayoutConfig
config.maxRecvNum = 0;
config.updateSize = false;
config.screenInfos = [{
screenId: "main",
screenWidth: width,
screenHeigh: height,
maxDecoderNum: 0,
maxViewCountPerPage: 0,
layout: {
windowId: "main", // window id
layoutMode: XYSDKUnityLayoutMode.Speaker, // 布局模式
pageIndex: 0, // 0表示非对称布局,1表示对称第一屏 default -1
maxViewCountPerPage: 6, // 每一屏最大请流数量
viewId: -1, // force layout 时传递id
localContent: false, // 本地共享独立回显
onlyContent: false, // 仅共享屏幕入会
multipleSharedCount: 0,
forceUid: "",
templateId: "",
viewData: []
} // default layout
}]
config.pad = false;
config.initLayoutModes = [
XYSDKUnityLayoutMode.Speaker, // 非对称布局Speaker模式
XYSDKUnityLayoutMode.Gallery, // 对称布局gallery模式
XYSDKUnityLayoutMode.Chairman, // 主会场模式
XYSDKUnityLayoutMode.ContentOnly, // 仅共享屏幕 模式
XYSDKUnityLayoutMode.Page, // 翻页模式
XYSDKUnityLayoutMode.UiTemplate, // 自定义模式(该模式为预留模式)
XYSDKUnityLayoutMode.Avc, //avc 多画面
XYSDKUnityLayoutMode.Locked, // force
XYSDKUnityLayoutMode.SuperChairman, //超级主会场
XYSDKUnityLayoutMode.SoftEmpty, // 空请流 驾驶模式、
XYSDKUnityLayoutMode.SoftWhitboard, // 移动端白板模式、
XYSDKUnityLayoutMode.None // 清除所有模式
]
config.audioGalleryConfig = {
/* 窗口大小 */
viewW: 108,
viewH: 108,
/* 窗口间距 */
lineSpace: 30,
columnSpace: 0,
landscapeLineSpace: 8,
landscapeColumnSpace: 60
}
config.audioSpeakerConfig = {
/* as大窗口 */
asViewW: 236, // 236;
asViewH: 184, // 184;
/* 小窗口 */
viewW: 108, // 108;
viewH: 108, // 108;
/* 只有两个的时候间距 */
viewColumnSpace_twoItem: 30, // 30;
/* 小窗口间隙 */
viewLineSpace: 30,// 30;
viewColumnSpace: 0, // 0
landscapeViewLineSpace : 30,// 30;
landscapeViewColumnSpace: 0, // 0
/* 小窗口相对as大窗口偏移 */
viewOppositeASOffset: 110, // 110;
landscapeViewOppositeASOffset: 50, // 50;
}
config.audioSmallConfig = {
viewW: 100, // 100;
viewH: 100, // 100;
rightMargin: 10, // 10;
topMargin: 0, // 56;
landscapeLeftMargin: 10, // 10;
landscapeBottomMargin: 10, // 10;
};
config.videoConfig = {
density: 1, //;
viewLineSpace: 2, // 2;
viewColumnSpace: 2, // 2;
landscapeSymmetryViewLeftMargin: 0, // 0
landscapeSymmetryViewRightMargin: 0, // 0
smallViewBottomMargin: 5, // 5;
smallViewLeftMargin: 5, // 5;
smallViewRightMargin: 5, // 5;
smallViewColumnSpace: 5, // 5;
};
return config;
}
let unityLayoutConfig = XYSDKInterFaceInstall.getSDKUnityLayoutLayoutConfigInstall(this.layoutViewWidth, this.layoutViewHeight);
unityLayoutConfig.updateSize = false;
unityLayoutConfig.pad = XYDeviceUtil.isPad();
XYRTCEngine.getInstance().setUnityLayoutConfig(unityLayoutConfig);
布局最佳体验
接下来统一了解一下changeLayout函数中XYSDKUnityLayoutRequest中常用到的字段参数:
export interface XYSDKUnityLayoutRequest {
/**
* window id 请传main
*/
windowId: string; //
/**
* 布局模式,
* 第一页 使用Speaker模式,
* 其他页使用Page模式,
* 如果锁定画面请使用 Locked模式, 并传入forceUid(取值回流中uniqueId字段)
* 自定义请流模版请使用 UiTemplate, 并传入viewData数据
* 在会中不需要显示layout时, 可以使用SoftEmpty模式, 减少相关性能消耗
*/
layoutMode: XYSDKUnityLayoutMode; //
/**
* 0表示非对称布局,1表示对称第一屏 default -1
*/
pageIndex: number; //
/**
* 每一屏最大请流数量
*/
maxViewCountPerPage: number; //
/**
* 移动端 为0
*/
viewId: number; //
/**
* 本地共享独立回显
*/
localContent: boolean; //
/**
* 仅共享屏幕入会
*/
onlyContent: boolean; //
/**
* force layout uid
*/
forceUid: string; //
/**
* 多路content支持数量, 最大4
*/
multipleSharedCount: number; //
/**
* 自定义请流模版id
*/
templateId: string; //
/**
* 自定义请流数据
*/
viewData: XYSDKUnityLayoutView[];
}
监听会议变化:
onConfInfoChanged(info: XYSDKConfInfo) {
this.confInfo = info;
this.hasContent = info.contentTotalNum > 0;
this.handelChairManUrlUpdate(info.chairManUrl);
this.showPeopleCount = info.displayableEpCount;
this.updateMultiContentStatus();
this.calculateVideoPageLength();
this.calculateAudioPageLength();
this.updatePipEnableStatus(!this.isRequestedLayout);
XYMeetingLayoutLog.info(`${TAG} onConfInfoChanged vu: ${this.videoPageCount} au: ${this.audioPageCount} ${JSON.stringify(info)}`);
if (!this.isRequestedLayout) {
this.requestLayout(this.index)
this.isRequestedLayout = true;
} else if (this.index >= this.totalCount()) {
this.index = this.totalCount() - 1;
this.requestLayout(this.index);
}
}
计算请流 changeLayout:
private requestLayout(index: number) {
let pageModel = this.getLayoutPageModel(this.index);
let info: XYSDKUnityLayoutRequest = XYSDKInterFaceInstall.getSDKUnityLayoutRequestInstall();
info.pageIndex = index;
info.maxViewCountPerPage = this.getLayoutMaxPerPage(index);
if (pageModel.forceUniqueId.length > 0) {
info.layoutMode = XYSDKUnityLayoutMode.Locked;
info.forceUid = pageModel.forceUniqueId;
} else {
info.layoutMode = index < 1 ? XYSDKUnityLayoutMode.Speaker : XYSDKUnityLayoutMode.Page;
}
let clientConfig = XYRTCEngine.getInstance().clientConfig;
if (clientConfig) {
info.multipleSharedCount = clientConfig.enterpriseConfig.enableMultipleShared ? clientConfig.enterpriseConfig.multipleSharedCount : 0;
}
XYMeetingLayoutLog.info(`${TAG} requestLayout: ${JSON.stringify(info)}`);
XYRTCEngine.getInstance().changeLayout([info]);
}
private getLayoutPageModel(index: number): XYLayoutPageModel {
let pageModel = this.layoutPageSet.get(index)
if (pageModel == undefined) {
pageModel = new XYLayoutPageModel(index);
this.layoutPageSet.set(index, pageModel);
}
return pageModel;
}
接收视频流回调:
onVideoStreamChanged(streamArray: XYSDKVideoStreamInfo[]) {
XYMeetingLayoutLog.info(`${TAG} videoStreamChanged enter ${streamArray.length}`);
let layoutMode: XYLayoutPageModel = this.getLayoutPageModel(this.index);
this.updateLayoutVideoModel(layoutMode, streamArray);
this.layoutPageSet.set(this.index, layoutMode);
XYMeetingLayoutLog.info(`${TAG} videoStreamChanged end`);
}
视频流渲染:
XYVideoRender({videoInfo: this.videoModel.streamInfo(接收到的视频流信息), renderColor: ...})
onVideoStreamChanged中返回的local只是占位, 需要自己匹配callUri, 并且非content, 更新videoSourceId、videoState等信息; 音视频状态自行维护更新. videoSourceId获取api如下:
XYRTCEngine.getInstance().getLocalSourceID();