trtc-electron-sdk
Version:
trtc electron sdk
137 lines (136 loc) • 7.17 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const BaseStreamLayoutManager_1 = __importDefault(require("./BaseStreamLayoutManager"));
const types_1 = require("../types");
const trtc_define_1 = require("../../../trtc_define");
const logger_1 = __importDefault(require("../../../logger"));
const constant_1 = require("../../../constant");
class CustomStreamLayoutManager extends BaseStreamLayoutManager_1.default {
constructor(nativeStreamLayoutManager, context) {
super(nativeStreamLayoutManager, context);
this.logPrefix = "[TRTCCustomStreamLayoutManager]";
this.layout = {
layoutMode: types_1.TRTCStreamLayoutMode.Custom,
};
}
setLayout(layout) {
this.layout = Object.assign(Object.assign({}, layout), { layoutMode: types_1.TRTCStreamLayoutMode.Custom });
this.refreshLayout();
}
refreshLayout() {
var _a;
if (this.layout.userList) {
let transferredUserList = this.layout.userList;
if (this.container) {
transferredUserList = this.layout.userList.map((user) => {
if (user.rect) {
return Object.assign(Object.assign({}, user), { rect: {
left: Math.round(user.rect.left * window.devicePixelRatio),
right: Math.round(user.rect.right * window.devicePixelRatio),
top: Math.round(user.rect.top * window.devicePixelRatio),
bottom: Math.round(user.rect.bottom * window.devicePixelRatio),
} });
}
else {
return user;
}
});
}
logger_1.default.debug(`${this.logPrefix}refreshLayout:`, JSON.stringify(transferredUserList));
this.nativeStreamLayoutManager.setStreamLayout(transferredUserList);
}
else if (this.layout.size && this.layout.streams) {
const userList = this.convertRelativeToAbsolute(this.layout);
if (userList) {
logger_1.default.debug(`${this.logPrefix}refreshLayout userList:`, userList);
const localUser = userList.filter(user => user.userId === constant_1.LOCAL_USER_ID)[0];
if ((localUser === null || localUser === void 0 ? void 0 : localUser.rect) && ((_a = this.context) === null || _a === void 0 ? void 0 : _a.mediaMixingDesigner)) {
const workingArea = localUser.rect;
this.context.mediaMixingDesigner.setWorkingArea({
left: workingArea.left / this.displayArea.width,
top: workingArea.top / this.displayArea.height,
right: workingArea.right / this.displayArea.width,
bottom: workingArea.bottom / this.displayArea.height,
}, localUser.fillMode);
}
userList.forEach(user => {
if (user.rect) {
user.rect = {
left: user.rect.left * window.devicePixelRatio,
right: user.rect.right * window.devicePixelRatio,
top: user.rect.top * window.devicePixelRatio,
bottom: user.rect.bottom * window.devicePixelRatio,
};
}
});
logger_1.default.debug(`${this.logPrefix}refreshLayout transfer layout to pixel unit::`, userList);
this.nativeStreamLayoutManager.setStreamLayout(userList);
}
else {
logger_1.default.error(`${this.logPrefix}refreshLayout invalid parameter, no 'streams' or 'size'`, JSON.stringify(this.layout));
}
}
else {
logger_1.default.error(`${this.logPrefix}refreshLayout invalid parameter:`, JSON.stringify(this.layout));
}
}
convertRelativeToAbsolute(serverMixingLayout) {
if (!serverMixingLayout.streams || !serverMixingLayout.size) {
return null;
}
// 1. calculate valid video content width and height
let minX = 1;
let minY = 1;
let maxX = 0;
let maxY = 0;
for (let i = 0; i < serverMixingLayout.streams.length; i++) {
const stream = serverMixingLayout.streams[i];
minX = Math.min(minX, stream.x);
minY = Math.min(minY, stream.y);
maxX = Math.max(maxX, stream.x + stream.w);
maxY = Math.max(maxY, stream.y + stream.h);
}
const xLength = maxX - minX;
const yLength = maxY - minY;
const contentWidth = xLength * serverMixingLayout.size.width;
const contentHeight = yLength * serverMixingLayout.size.height;
// 2. calculate fitting scale rate and fitting area
const scaleRate = Math.min(this.displayArea.width / contentWidth, this.displayArea.height / contentHeight);
const fittingArea = {
width: contentWidth * scaleRate,
height: contentHeight * scaleRate,
left: (this.displayArea.width - contentWidth * scaleRate) / 2,
top: (this.displayArea.height - contentHeight * scaleRate) / 2,
right: (this.displayArea.width + contentWidth * scaleRate) / 2,
bottom: (this.displayArea.height + contentHeight * scaleRate) / 2,
};
// 3. transfer relative coordinates to absolute coordinates
return serverMixingLayout.streams.map((stream, index, list) => {
// 3.1 cut left and top black area
// 3.2 transfer relative video ratio to valid video content ratio
// 3.3 fit valid video content to dispaying area, that is fitting area
const result = {
x: (stream.x - minX) / xLength * contentWidth * scaleRate + fittingArea.left,
y: (stream.y - minY) / yLength * contentHeight * scaleRate + fittingArea.top,
w: (stream.w) / xLength * contentWidth * scaleRate,
h: (stream.h) / yLength * contentHeight * scaleRate,
};
// 3.4 convert to TRTCStreamLayout.userList item
return {
userId: stream.userId,
fillMode: list.length >= 2 ? trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fill : trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fit,
zOrder: index,
rect: {
left: Math.round(result.x),
top: Math.round(result.y),
right: Math.round(result.x + result.w),
bottom: Math.round(result.y + result.h),
}
};
});
}
}
exports.default = CustomStreamLayoutManager;