UNPKG

trtc-electron-sdk

Version:

trtc electron sdk

137 lines (136 loc) 7.17 kB
"use strict"; 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;