trtc-electron-sdk 12.2.115-beta.2 → 12.2.115-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/liteav/MediaMixingDesigner/index.d.ts +12 -8
- package/liteav/MediaMixingDesigner/index.js +135 -79
- package/liteav/base/DevicePixelRatioObserver.d.ts +12 -0
- package/liteav/base/DevicePixelRatioObserver.js +32 -0
- package/liteav/base/PromiseStore.d.ts +10 -0
- package/liteav/base/PromiseStore.js +58 -0
- package/liteav/constant.d.ts +1 -0
- package/liteav/constant.js +4 -0
- package/liteav/extensions/MediaMixingManager/MediaMixingManager.d.ts +429 -0
- package/liteav/extensions/MediaMixingManager/MediaMixingManager.js +1290 -0
- package/liteav/extensions/MediaMixingManager/MediaMixingService.d.ts +60 -0
- package/liteav/extensions/MediaMixingManager/MediaMixingService.js +80 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/BaseStreamLayoutManager.d.ts +32 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/BaseStreamLayoutManager.js +114 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/CustomStreamLayoutManager.d.ts +11 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/CustomStreamLayoutManager.js +135 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/NoneStreamLayoutManager.d.ts +11 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/NoneStreamLayoutManager.js +73 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/index.d.ts +7 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/index.js +34 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/types.d.ts +25 -0
- package/liteav/extensions/MediaMixingManager/StreamLayout/types.js +2 -0
- package/liteav/extensions/MediaMixingManager/index.d.ts +4 -227
- package/liteav/extensions/MediaMixingManager/index.js +30 -589
- package/liteav/extensions/MediaMixingManager/types.d.ts +107 -0
- package/liteav/extensions/MediaMixingManager/types.js +26 -0
- package/liteav/trtc.d.ts +67 -13
- package/liteav/trtc.js +159 -61
- package/liteav/trtc_define.d.ts +29 -3
- package/liteav/trtc_define.js +97 -29
- package/liteav/utils.d.ts +27 -0
- package/liteav/utils.js +85 -1
- package/package.json +2 -2
- package/scripts/download.js +153 -169
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import TRTCMediaMixingManager from './MediaMixingManager';
|
|
2
|
+
import { ITRTCMediaMixingService } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* @namespace TRTCMediaMixingServiceEvent
|
|
5
|
+
* @description 目前只支持 `Windows` 操作系统
|
|
6
|
+
*/
|
|
7
|
+
export declare enum TRTCMediaMixingServiceEvent {
|
|
8
|
+
/**
|
|
9
|
+
* @description 本地混流服务器连接丢失事件
|
|
10
|
+
*
|
|
11
|
+
* @event TRTCMediaMixingServiceEvent#onMediaMixingServerLost
|
|
12
|
+
*/
|
|
13
|
+
onMediaMixingServerLost = "onMediaMixingServerLost"
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 本地混流服务
|
|
17
|
+
*
|
|
18
|
+
* 目前只支持 `Windows` 操作系统
|
|
19
|
+
*/
|
|
20
|
+
declare class TRTCMediaMixingService implements ITRTCMediaMixingService {
|
|
21
|
+
private mediaMixingManager;
|
|
22
|
+
private eventEmitter;
|
|
23
|
+
constructor(mediaMixingManager: TRTCMediaMixingManager);
|
|
24
|
+
/**
|
|
25
|
+
* 启动独立混流渲染进程
|
|
26
|
+
*
|
|
27
|
+
* 开发模式,默认路径:node_modules\\trtc-electron-sdk\\build\\Release\\liteav_media_server.exe
|
|
28
|
+
*
|
|
29
|
+
* 构建模式,默认路径:${resourcesPath}\\liteav_media_server.exe
|
|
30
|
+
*
|
|
31
|
+
* 如果用户应用有特殊配置,默认路径可能找不到服务进程程序,需要自行传入路径。
|
|
32
|
+
*
|
|
33
|
+
* @param path {string} - 服务进程程序路径,不传入参数时,SDK 内部按照默认路径启动服务进程。
|
|
34
|
+
*
|
|
35
|
+
* @returns {Promise<void>}
|
|
36
|
+
*/
|
|
37
|
+
startMediaMixingServer(path?: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* 关闭独立混流渲染进程
|
|
40
|
+
*
|
|
41
|
+
* @returns {Promise<void>}
|
|
42
|
+
*/
|
|
43
|
+
stopMediaMixingServer(): Promise<void>;
|
|
44
|
+
destroy(): void;
|
|
45
|
+
/**
|
|
46
|
+
* 注册事件监听
|
|
47
|
+
*
|
|
48
|
+
* @param event {TRTCMediaMixingServiceEvent} - 事件名称
|
|
49
|
+
* @param func {Function} - 事件回调函数
|
|
50
|
+
*/
|
|
51
|
+
on(event: TRTCMediaMixingServiceEvent, func: (...args: any[]) => void): void;
|
|
52
|
+
/**
|
|
53
|
+
* 取消事件监听
|
|
54
|
+
*
|
|
55
|
+
* @param event {TRTCMediaMixingServiceEvent} - 事件名
|
|
56
|
+
* @param func {Function} - 事件回调函数
|
|
57
|
+
*/
|
|
58
|
+
off(event: TRTCMediaMixingServiceEvent, func: (...args: any[]) => void): void;
|
|
59
|
+
}
|
|
60
|
+
export default TRTCMediaMixingService;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TRTCMediaMixingServiceEvent = void 0;
|
|
4
|
+
const events_1 = require("events");
|
|
5
|
+
const MediaMixingManager_1 = require("./MediaMixingManager");
|
|
6
|
+
/**
|
|
7
|
+
* @namespace TRTCMediaMixingServiceEvent
|
|
8
|
+
* @description 目前只支持 `Windows` 操作系统
|
|
9
|
+
*/
|
|
10
|
+
var TRTCMediaMixingServiceEvent;
|
|
11
|
+
(function (TRTCMediaMixingServiceEvent) {
|
|
12
|
+
/**
|
|
13
|
+
* @description 本地混流服务器连接丢失事件
|
|
14
|
+
*
|
|
15
|
+
* @event TRTCMediaMixingServiceEvent#onMediaMixingServerLost
|
|
16
|
+
*/
|
|
17
|
+
TRTCMediaMixingServiceEvent["onMediaMixingServerLost"] = "onMediaMixingServerLost";
|
|
18
|
+
})(TRTCMediaMixingServiceEvent = exports.TRTCMediaMixingServiceEvent || (exports.TRTCMediaMixingServiceEvent = {}));
|
|
19
|
+
/**
|
|
20
|
+
* 本地混流服务
|
|
21
|
+
*
|
|
22
|
+
* 目前只支持 `Windows` 操作系统
|
|
23
|
+
*/
|
|
24
|
+
class TRTCMediaMixingService {
|
|
25
|
+
constructor(mediaMixingManager) {
|
|
26
|
+
this.mediaMixingManager = mediaMixingManager;
|
|
27
|
+
this.eventEmitter = new events_1.EventEmitter();
|
|
28
|
+
this.mediaMixingManager.on(MediaMixingManager_1.TRTCMediaMixingEvent.onMediaMixingServerLost, () => {
|
|
29
|
+
this.eventEmitter.emit(TRTCMediaMixingServiceEvent.onMediaMixingServerLost);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 启动独立混流渲染进程
|
|
34
|
+
*
|
|
35
|
+
* 开发模式,默认路径:node_modules\\trtc-electron-sdk\\build\\Release\\liteav_media_server.exe
|
|
36
|
+
*
|
|
37
|
+
* 构建模式,默认路径:${resourcesPath}\\liteav_media_server.exe
|
|
38
|
+
*
|
|
39
|
+
* 如果用户应用有特殊配置,默认路径可能找不到服务进程程序,需要自行传入路径。
|
|
40
|
+
*
|
|
41
|
+
* @param path {string} - 服务进程程序路径,不传入参数时,SDK 内部按照默认路径启动服务进程。
|
|
42
|
+
*
|
|
43
|
+
* @returns {Promise<void>}
|
|
44
|
+
*/
|
|
45
|
+
startMediaMixingServer(path) {
|
|
46
|
+
return this.mediaMixingManager.startMediaMixingServer(path);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 关闭独立混流渲染进程
|
|
50
|
+
*
|
|
51
|
+
* @returns {Promise<void>}
|
|
52
|
+
*/
|
|
53
|
+
stopMediaMixingServer() {
|
|
54
|
+
return this.mediaMixingManager.stopMediaMixingServer();
|
|
55
|
+
}
|
|
56
|
+
destroy() {
|
|
57
|
+
this.eventEmitter.removeAllListeners();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 注册事件监听
|
|
61
|
+
*
|
|
62
|
+
* @param event {TRTCMediaMixingServiceEvent} - 事件名称
|
|
63
|
+
* @param func {Function} - 事件回调函数
|
|
64
|
+
*/
|
|
65
|
+
on(event, func) {
|
|
66
|
+
var _a;
|
|
67
|
+
(_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.on(event, func);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 取消事件监听
|
|
71
|
+
*
|
|
72
|
+
* @param event {TRTCMediaMixingServiceEvent} - 事件名
|
|
73
|
+
* @param func {Function} - 事件回调函数
|
|
74
|
+
*/
|
|
75
|
+
off(event, func) {
|
|
76
|
+
var _a;
|
|
77
|
+
(_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.off(event, func);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.default = TRTCMediaMixingService;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { TRTCStreamLayout, TRTCStreamLayoutMode } from "../types";
|
|
2
|
+
import { ITRTCStreamLayoutManager, INativeStreamLayoutManager, TRTCStreamLayoutContext } from "./types";
|
|
3
|
+
declare class BaseStreamLayoutManager implements ITRTCStreamLayoutManager {
|
|
4
|
+
protected logPrefix: string;
|
|
5
|
+
protected nativeStreamLayoutManager: INativeStreamLayoutManager;
|
|
6
|
+
protected layout: TRTCStreamLayout;
|
|
7
|
+
protected context: TRTCStreamLayoutContext | null;
|
|
8
|
+
protected container: HTMLElement | null;
|
|
9
|
+
protected displayArea: {
|
|
10
|
+
left: number;
|
|
11
|
+
top: number;
|
|
12
|
+
right: number;
|
|
13
|
+
bottom: number;
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
};
|
|
17
|
+
protected resizeObserver: ResizeObserver | null;
|
|
18
|
+
constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context: TRTCStreamLayoutContext);
|
|
19
|
+
setLayout(layout: TRTCStreamLayout): void;
|
|
20
|
+
getLayoutMode(): TRTCStreamLayoutMode;
|
|
21
|
+
updateOptions(options: {
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
}): void;
|
|
25
|
+
destroy(): void;
|
|
26
|
+
protected refreshLayout(): void;
|
|
27
|
+
private onResize;
|
|
28
|
+
private setResizeObserver;
|
|
29
|
+
private updateDisplayArea;
|
|
30
|
+
private onDevicePixelRatioChange;
|
|
31
|
+
}
|
|
32
|
+
export default BaseStreamLayoutManager;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
const DevicePixelRatioObserver_1 = __importDefault(require("../../../base/DevicePixelRatioObserver"));
|
|
8
|
+
const utils_1 = require("../../../utils");
|
|
9
|
+
const logger_1 = __importDefault(require("../../../logger"));
|
|
10
|
+
class BaseStreamLayoutManager {
|
|
11
|
+
constructor(nativeStreamLayoutManager, context) {
|
|
12
|
+
this.logPrefix = "[BaseStreamLayoutManager]";
|
|
13
|
+
this.container = null;
|
|
14
|
+
this.displayArea = {
|
|
15
|
+
left: 0,
|
|
16
|
+
top: 0,
|
|
17
|
+
right: 0,
|
|
18
|
+
bottom: 0,
|
|
19
|
+
width: 0,
|
|
20
|
+
height: 0,
|
|
21
|
+
};
|
|
22
|
+
this.resizeObserver = null;
|
|
23
|
+
this.nativeStreamLayoutManager = nativeStreamLayoutManager;
|
|
24
|
+
this.layout = {
|
|
25
|
+
layoutMode: types_1.TRTCStreamLayoutMode.None,
|
|
26
|
+
};
|
|
27
|
+
this.context = context;
|
|
28
|
+
this.container = context.container;
|
|
29
|
+
this.onResize = (0, utils_1.debounce)(this.onResize.bind(this), 100);
|
|
30
|
+
if (this.container) {
|
|
31
|
+
this.setResizeObserver();
|
|
32
|
+
this.updateDisplayArea();
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
logger_1.default.warn(`${this.logPrefix}constructor failed, no context.container.`);
|
|
36
|
+
}
|
|
37
|
+
this.onDevicePixelRatioChange = (0, utils_1.debounce)(this.onDevicePixelRatioChange.bind(this), 100);
|
|
38
|
+
DevicePixelRatioObserver_1.default.on('change', this.onDevicePixelRatioChange);
|
|
39
|
+
}
|
|
40
|
+
setLayout(layout) {
|
|
41
|
+
this.layout = layout;
|
|
42
|
+
this.refreshLayout();
|
|
43
|
+
}
|
|
44
|
+
getLayoutMode() {
|
|
45
|
+
return this.layout.layoutMode;
|
|
46
|
+
}
|
|
47
|
+
updateOptions(options) {
|
|
48
|
+
if (this.context && (this.context.mixingVideoSize.width !== options.width || this.context.mixingVideoSize.height !== options.height)) {
|
|
49
|
+
this.context.mixingVideoSize.width = options.width;
|
|
50
|
+
this.context.mixingVideoSize.height = options.height;
|
|
51
|
+
this.refreshLayout();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
destroy() {
|
|
55
|
+
this.layout = {
|
|
56
|
+
layoutMode: types_1.TRTCStreamLayoutMode.None,
|
|
57
|
+
};
|
|
58
|
+
this.container = null;
|
|
59
|
+
this.context = null;
|
|
60
|
+
if (this.resizeObserver) {
|
|
61
|
+
this.resizeObserver.disconnect();
|
|
62
|
+
this.resizeObserver = null;
|
|
63
|
+
}
|
|
64
|
+
DevicePixelRatioObserver_1.default.off('change', this.onDevicePixelRatioChange);
|
|
65
|
+
}
|
|
66
|
+
refreshLayout() {
|
|
67
|
+
logger_1.default.warn(`${this.logPrefix}refreshLayout should be implemented by sub-class.`);
|
|
68
|
+
}
|
|
69
|
+
onResize(entries) {
|
|
70
|
+
logger_1.default.log(`${this.logPrefix}onResize entries:`, entries);
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
if (entry.target === this.container) {
|
|
73
|
+
logger_1.default.debug(`${this.logPrefix}onResize:`, this.container.getBoundingClientRect());
|
|
74
|
+
this.updateDisplayArea();
|
|
75
|
+
this.refreshLayout();
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
setResizeObserver() {
|
|
81
|
+
logger_1.default.debug(`${this.logPrefix}setResizeObserver container:`, this.container, ' resizeObserver:', this.resizeObserver);
|
|
82
|
+
if (this.resizeObserver) {
|
|
83
|
+
this.resizeObserver.disconnect();
|
|
84
|
+
}
|
|
85
|
+
if (this.container) {
|
|
86
|
+
this.resizeObserver = new ResizeObserver(this.onResize);
|
|
87
|
+
this.resizeObserver.observe(this.container);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
logger_1.default.warn(`${this.logPrefix}setResizeObserver failed, container is null.`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
updateDisplayArea() {
|
|
94
|
+
if (this.container) {
|
|
95
|
+
const containerRect = this.container.getBoundingClientRect();
|
|
96
|
+
this.displayArea = {
|
|
97
|
+
left: containerRect.left,
|
|
98
|
+
top: containerRect.top,
|
|
99
|
+
right: containerRect.right,
|
|
100
|
+
bottom: containerRect.bottom,
|
|
101
|
+
width: containerRect.width,
|
|
102
|
+
height: containerRect.height,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
logger_1.default.warn(`${this.logPrefix}updateDisplayArea failed, no container.`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
onDevicePixelRatioChange() {
|
|
110
|
+
logger_1.default.debug(`${this.logPrefix}onDevicePixelRatioChange:`, window.devicePixelRatio);
|
|
111
|
+
this.refreshLayout();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.default = BaseStreamLayoutManager;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import BaseStreamLayoutManager from "./BaseStreamLayoutManager";
|
|
2
|
+
import { TRTCStreamLayout } from "../types";
|
|
3
|
+
import { INativeStreamLayoutManager, TRTCStreamLayoutContext } from "./types";
|
|
4
|
+
declare class CustomStreamLayoutManager extends BaseStreamLayoutManager {
|
|
5
|
+
protected logPrefix: string;
|
|
6
|
+
constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context: TRTCStreamLayoutContext);
|
|
7
|
+
setLayout(layout: TRTCStreamLayout): void;
|
|
8
|
+
protected refreshLayout(): void;
|
|
9
|
+
private convertRelativeToAbsolute;
|
|
10
|
+
}
|
|
11
|
+
export default CustomStreamLayoutManager;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const BaseStreamLayoutManager_1 = __importDefault(require("./BaseStreamLayoutManager"));
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const trtc_define_1 = require("../../../trtc_define");
|
|
9
|
+
const logger_1 = __importDefault(require("../../../logger"));
|
|
10
|
+
const constant_1 = require("../../../constant");
|
|
11
|
+
class CustomStreamLayoutManager extends BaseStreamLayoutManager_1.default {
|
|
12
|
+
constructor(nativeStreamLayoutManager, context) {
|
|
13
|
+
super(nativeStreamLayoutManager, context);
|
|
14
|
+
this.logPrefix = "[TRTCCustomStreamLayoutManager]";
|
|
15
|
+
this.layout = {
|
|
16
|
+
layoutMode: types_1.TRTCStreamLayoutMode.Custom,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
setLayout(layout) {
|
|
20
|
+
this.layout = Object.assign(Object.assign({}, layout), { layoutMode: types_1.TRTCStreamLayoutMode.Custom });
|
|
21
|
+
this.refreshLayout();
|
|
22
|
+
}
|
|
23
|
+
refreshLayout() {
|
|
24
|
+
var _a;
|
|
25
|
+
if (this.layout.userList) {
|
|
26
|
+
let transferredUserList = this.layout.userList;
|
|
27
|
+
if (this.container) {
|
|
28
|
+
transferredUserList = this.layout.userList.map((user) => {
|
|
29
|
+
if (user.rect) {
|
|
30
|
+
return Object.assign(Object.assign({}, user), { rect: {
|
|
31
|
+
left: user.rect.left * window.devicePixelRatio,
|
|
32
|
+
right: user.rect.right * window.devicePixelRatio,
|
|
33
|
+
top: user.rect.top * window.devicePixelRatio,
|
|
34
|
+
bottom: user.rect.bottom * window.devicePixelRatio,
|
|
35
|
+
} });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
return user;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
this.nativeStreamLayoutManager.setStreamLayout(transferredUserList);
|
|
43
|
+
}
|
|
44
|
+
else if (this.layout.size && this.layout.streams) {
|
|
45
|
+
const userList = this.convertRelativeToAbsolute(this.layout);
|
|
46
|
+
if (userList) {
|
|
47
|
+
logger_1.default.debug(`${this.logPrefix}refreshLayout userList:`, userList);
|
|
48
|
+
const localUser = userList.filter(user => user.userId === constant_1.LOCAL_USER_ID)[0];
|
|
49
|
+
if ((localUser === null || localUser === void 0 ? void 0 : localUser.rect) && ((_a = this.context) === null || _a === void 0 ? void 0 : _a.mediaMixingDesigner)) {
|
|
50
|
+
const workingArea = localUser.rect;
|
|
51
|
+
this.context.mediaMixingDesigner.setWorkingArea({
|
|
52
|
+
left: workingArea.left / this.displayArea.width,
|
|
53
|
+
top: workingArea.top / this.displayArea.height,
|
|
54
|
+
right: workingArea.right / this.displayArea.width,
|
|
55
|
+
bottom: workingArea.bottom / this.displayArea.height,
|
|
56
|
+
}, localUser.fillMode);
|
|
57
|
+
}
|
|
58
|
+
userList.forEach(user => {
|
|
59
|
+
if (user.rect) {
|
|
60
|
+
user.rect = {
|
|
61
|
+
left: user.rect.left * window.devicePixelRatio,
|
|
62
|
+
right: user.rect.right * window.devicePixelRatio,
|
|
63
|
+
top: user.rect.top * window.devicePixelRatio,
|
|
64
|
+
bottom: user.rect.bottom * window.devicePixelRatio,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
logger_1.default.debug(`${this.logPrefix}refreshLayout transfer layout to pixel unit::`, userList);
|
|
69
|
+
this.nativeStreamLayoutManager.setStreamLayout(userList);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
logger_1.default.error(`${this.logPrefix}refreshLayout invalid parameter, no 'streams' or 'size'`, JSON.stringify(this.layout));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
logger_1.default.error(`${this.logPrefix}refreshLayout invalid parameter:`, JSON.stringify(this.layout));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
convertRelativeToAbsolute(serverMixingLayout) {
|
|
80
|
+
if (!serverMixingLayout.streams || !serverMixingLayout.size) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
// 1. calculate valid video content width and height
|
|
84
|
+
let minX = 1;
|
|
85
|
+
let minY = 1;
|
|
86
|
+
let maxX = 0;
|
|
87
|
+
let maxY = 0;
|
|
88
|
+
for (let i = 0; i < serverMixingLayout.streams.length; i++) {
|
|
89
|
+
const stream = serverMixingLayout.streams[i];
|
|
90
|
+
minX = Math.min(minX, stream.x);
|
|
91
|
+
minY = Math.min(minY, stream.y);
|
|
92
|
+
maxX = Math.max(maxX, stream.x + stream.w);
|
|
93
|
+
maxY = Math.max(maxY, stream.y + stream.h);
|
|
94
|
+
}
|
|
95
|
+
const xLength = maxX - minX;
|
|
96
|
+
const yLength = maxY - minY;
|
|
97
|
+
const contentWidth = xLength * serverMixingLayout.size.width;
|
|
98
|
+
const contentHeight = yLength * serverMixingLayout.size.height;
|
|
99
|
+
// 2. calculate fitting scale rate and fitting area
|
|
100
|
+
const scaleRate = Math.min(this.displayArea.width / contentWidth, this.displayArea.height / contentHeight);
|
|
101
|
+
const fittingArea = {
|
|
102
|
+
width: contentWidth * scaleRate,
|
|
103
|
+
height: contentHeight * scaleRate,
|
|
104
|
+
left: (this.displayArea.width - contentWidth * scaleRate) / 2,
|
|
105
|
+
top: (this.displayArea.height - contentHeight * scaleRate) / 2,
|
|
106
|
+
right: (this.displayArea.width + contentWidth * scaleRate) / 2,
|
|
107
|
+
bottom: (this.displayArea.height + contentHeight * scaleRate) / 2,
|
|
108
|
+
};
|
|
109
|
+
// 3. transfer relative coordinates to absolute coordinates
|
|
110
|
+
return serverMixingLayout.streams.map((stream, index, list) => {
|
|
111
|
+
// 3.1 cut left and top black area
|
|
112
|
+
// 3.2 transfer relative video ratio to valid video content ratio
|
|
113
|
+
// 3.3 fit valid video content to dispaying area, that is fitting area
|
|
114
|
+
const result = {
|
|
115
|
+
x: (stream.x - minX) / xLength * contentWidth * scaleRate + fittingArea.left,
|
|
116
|
+
y: (stream.y - minY) / yLength * contentHeight * scaleRate + fittingArea.top,
|
|
117
|
+
w: (stream.w) / xLength * contentWidth * scaleRate,
|
|
118
|
+
h: (stream.h) / yLength * contentHeight * scaleRate,
|
|
119
|
+
};
|
|
120
|
+
// 3.4 convert to TRTCStreamLayout.userList item
|
|
121
|
+
return {
|
|
122
|
+
userId: stream.userId,
|
|
123
|
+
fillMode: list.length >= 2 ? trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fill : trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fit,
|
|
124
|
+
zOrder: index,
|
|
125
|
+
rect: {
|
|
126
|
+
left: Math.round(result.x),
|
|
127
|
+
top: Math.round(result.y),
|
|
128
|
+
right: Math.round(result.x + result.w),
|
|
129
|
+
bottom: Math.round(result.y + result.h),
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.default = CustomStreamLayoutManager;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import BaseStreamLayoutManager from "./BaseStreamLayoutManager";
|
|
2
|
+
import { TRTCStreamLayout } from "../types";
|
|
3
|
+
import { INativeStreamLayoutManager, TRTCStreamLayoutContext } from "./types";
|
|
4
|
+
declare class NoneStreamLayoutManager extends BaseStreamLayoutManager {
|
|
5
|
+
protected logPrefix: string;
|
|
6
|
+
constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context: TRTCStreamLayoutContext);
|
|
7
|
+
setLayout(layout: TRTCStreamLayout): void;
|
|
8
|
+
protected refreshLayout(): void;
|
|
9
|
+
private centerLiveOwner;
|
|
10
|
+
}
|
|
11
|
+
export default NoneStreamLayoutManager;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const BaseStreamLayoutManager_1 = __importDefault(require("./BaseStreamLayoutManager"));
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const trtc_define_1 = require("../../../trtc_define");
|
|
9
|
+
const logger_1 = __importDefault(require("../../../logger"));
|
|
10
|
+
class NoneStreamLayoutManager extends BaseStreamLayoutManager_1.default {
|
|
11
|
+
constructor(nativeStreamLayoutManager, context) {
|
|
12
|
+
super(nativeStreamLayoutManager, context);
|
|
13
|
+
this.logPrefix = "[TRTCNoneStreamLayoutManager]";
|
|
14
|
+
}
|
|
15
|
+
setLayout(layout) {
|
|
16
|
+
this.layout = Object.assign(Object.assign({}, layout), { layoutMode: types_1.TRTCStreamLayoutMode.None, userList: [] });
|
|
17
|
+
this.refreshLayout();
|
|
18
|
+
}
|
|
19
|
+
refreshLayout() {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
if (this.context && this.layout.userList) {
|
|
22
|
+
this.centerLiveOwner();
|
|
23
|
+
if (this.layout.userList.length === 1 && this.layout.userList[0].rect && this.displayArea.width !== 0 && this.displayArea.height !== 0 && window.devicePixelRatio !== 0) {
|
|
24
|
+
const workingArea = this.layout.userList[0].rect;
|
|
25
|
+
(_a = this.context.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.setWorkingArea({
|
|
26
|
+
left: workingArea.left / this.displayArea.width / window.devicePixelRatio,
|
|
27
|
+
top: workingArea.top / this.displayArea.height / window.devicePixelRatio,
|
|
28
|
+
right: workingArea.right / this.displayArea.width / window.devicePixelRatio,
|
|
29
|
+
bottom: workingArea.bottom / this.displayArea.height / window.devicePixelRatio,
|
|
30
|
+
}, this.layout.userList[0].fillMode);
|
|
31
|
+
}
|
|
32
|
+
(_b = this.nativeStreamLayoutManager) === null || _b === void 0 ? void 0 : _b.setStreamLayout(this.layout.userList);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
logger_1.default.error(`${this.logPrefix}refreshLayout context is null or no user`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
centerLiveOwner() {
|
|
39
|
+
if (this.context && this.layout) {
|
|
40
|
+
const layoutPixelWidth = this.displayArea.width * window.devicePixelRatio;
|
|
41
|
+
const layoutPixelHeight = this.displayArea.height * window.devicePixelRatio;
|
|
42
|
+
const mixingVideoWidth = this.context.mixingVideoSize.width;
|
|
43
|
+
const mixingVideoHeight = this.context.mixingVideoSize.height;
|
|
44
|
+
// Live Owner(local user)
|
|
45
|
+
let scaleRate;
|
|
46
|
+
if (mixingVideoWidth === 0 || mixingVideoHeight === 0) {
|
|
47
|
+
scaleRate = 1;
|
|
48
|
+
logger_1.default.error(`${this.logPrefix}centerLiveOwner mixingVideoSize is 0, use default scaleRate '1'`);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
scaleRate = Math.min(layoutPixelWidth / mixingVideoWidth, layoutPixelHeight / mixingVideoHeight);
|
|
52
|
+
}
|
|
53
|
+
const previewWidth = mixingVideoWidth * scaleRate;
|
|
54
|
+
const previewHeight = mixingVideoHeight * scaleRate;
|
|
55
|
+
const previewLeft = (layoutPixelWidth - previewWidth) / 2;
|
|
56
|
+
const previewTop = (layoutPixelHeight - previewHeight) / 2;
|
|
57
|
+
const previewRight = previewLeft + previewWidth;
|
|
58
|
+
const previewBottom = previewTop + previewHeight;
|
|
59
|
+
this.layout.userList = [{
|
|
60
|
+
userId: '',
|
|
61
|
+
rect: {
|
|
62
|
+
left: previewLeft,
|
|
63
|
+
top: previewTop,
|
|
64
|
+
right: previewRight,
|
|
65
|
+
bottom: previewBottom,
|
|
66
|
+
},
|
|
67
|
+
fillMode: trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fit,
|
|
68
|
+
zOrder: 0
|
|
69
|
+
}];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.default = NoneStreamLayoutManager;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { TRTCStreamLayoutMode } from '../types';
|
|
2
|
+
import { ITRTCStreamLayoutManager, INativeStreamLayoutManager, TRTCStreamLayoutContext } from './types';
|
|
3
|
+
export * from './types';
|
|
4
|
+
declare function create(layoutMode: TRTCStreamLayoutMode, nativeStreamLayoutManager: INativeStreamLayoutManager, context: TRTCStreamLayoutContext): ITRTCStreamLayoutManager;
|
|
5
|
+
export declare const StreamLayoutFactory: {
|
|
6
|
+
create: typeof create;
|
|
7
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.StreamLayoutFactory = void 0;
|
|
17
|
+
const CustomStreamLayoutManager_1 = __importDefault(require("./CustomStreamLayoutManager"));
|
|
18
|
+
const NoneStreamLayoutManager_1 = __importDefault(require("./NoneStreamLayoutManager"));
|
|
19
|
+
const types_1 = require("../types");
|
|
20
|
+
__exportStar(require("./types"), exports);
|
|
21
|
+
function create(layoutMode, nativeStreamLayoutManager, context) {
|
|
22
|
+
let layoutManager;
|
|
23
|
+
if (layoutMode === types_1.TRTCStreamLayoutMode.Custom) {
|
|
24
|
+
layoutManager = new CustomStreamLayoutManager_1.default(nativeStreamLayoutManager, context);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// layoutMode === TRTCStreamLayoutMode.None
|
|
28
|
+
layoutManager = new NoneStreamLayoutManager_1.default(nativeStreamLayoutManager, context);
|
|
29
|
+
}
|
|
30
|
+
return layoutManager;
|
|
31
|
+
}
|
|
32
|
+
exports.StreamLayoutFactory = {
|
|
33
|
+
create: create,
|
|
34
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { TRTCUserStream, TRTCStreamLayout, TRTCStreamLayoutMode } from '../types';
|
|
2
|
+
import TRTCMediaMixingDesigner from '../../../MediaMixingDesigner';
|
|
3
|
+
export interface INativeStreamLayoutManager {
|
|
4
|
+
setStreamLayout: (streamList: Array<TRTCUserStream>) => void;
|
|
5
|
+
}
|
|
6
|
+
export interface TRTCStreamLayoutContext {
|
|
7
|
+
container: HTMLElement | null;
|
|
8
|
+
mixingVideoSize: {
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
};
|
|
12
|
+
mediaMixingDesigner: TRTCMediaMixingDesigner | null;
|
|
13
|
+
}
|
|
14
|
+
export interface ITRTCStreamLayoutManager {
|
|
15
|
+
setLayout(layout: TRTCStreamLayout): void;
|
|
16
|
+
getLayoutMode(): TRTCStreamLayoutMode;
|
|
17
|
+
updateOptions(options: {
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
}): void;
|
|
21
|
+
destroy(): void;
|
|
22
|
+
}
|
|
23
|
+
export interface ITRTCStreamLayoutEvent {
|
|
24
|
+
onStreamLayoutChanged(streams: Array<TRTCUserStream>): void;
|
|
25
|
+
}
|