trtc-electron-sdk 10.0.100-beta.8 → 10.2.0-beta.0

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.
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const EventEmitter = require('events').EventEmitter;
13
+ const isEqual = require('lodash.isequal');
14
+ const { calcVideoStyle } = require('../util');
15
+ /* contentMode
16
+ * - 0: Cropped mode. Uniformly scale the video until it fills the visible boundaries (cropped).
17
+ * One dimension of the video may have clipped contents.
18
+ * - 1: Fit mode. Uniformly scale the video until one of its dimension fits the boundary (zoomed to fit).
19
+ * Areas that are not filled due to the disparity in the aspect ratio will be filled with black.
20
+ */
21
+ class BGRAVideoRenderer {
22
+ constructor() {
23
+ this.cachedOptions = {};
24
+ this.event = new EventEmitter();
25
+ this.element = null;
26
+ this.video = document.createElement('video');
27
+ this.video.setAttribute('style', 'width: 100%; height: 100%; display: block; margin: 0 auto;');
28
+ this.video.setAttribute('autoplay', 'autoplay');
29
+ this.video.muted = true;
30
+ this.contentMode = 1;
31
+ this.ready = false;
32
+ this.track = new MediaStreamTrackGenerator({ kind: 'video' });
33
+ this.writer = this.track.writable.getWriter();
34
+ }
35
+ getView() {
36
+ return this.element;
37
+ }
38
+ _updateStyle(options = {
39
+ contentWidth: 0,
40
+ contentHeight: 0,
41
+ rotation: 0,
42
+ mirrorView: false,
43
+ contentMode: 0,
44
+ containerWidth: 0,
45
+ containerHeight: 0,
46
+ isNeedRotate: true
47
+ }) {
48
+ if (isEqual(this.cachedOptions, options)) {
49
+ return;
50
+ }
51
+ this.cachedOptions = Object.assign({}, options);
52
+ const style = calcVideoStyle(options);
53
+ Object.keys(style).forEach(key => {
54
+ this.video.style[key] = style[key];
55
+ });
56
+ }
57
+ drawFrame(frameData) {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ if (!this.ready) {
60
+ this.ready = true;
61
+ this.event.emit('ready');
62
+ }
63
+ this._updateStyle({
64
+ rotation: frameData.rotation,
65
+ isNeedRotate: frameData.isNeedRotate,
66
+ contentWidth: frameData.width,
67
+ contentHeight: frameData.height,
68
+ contentMode: this.contentMode,
69
+ mirrorView: false,
70
+ containerWidth: this.element.clientWidth,
71
+ containerHeight: this.element.clientHeight,
72
+ });
73
+ if (global.bgraFrames) {
74
+ global.bgraFrames.push(frameData);
75
+ if (global.bgraFrames.length > 100) {
76
+ global.bgraFrames.shift();
77
+ }
78
+ }
79
+ else {
80
+ global.bgraFrames = [frameData];
81
+ }
82
+ try {
83
+ const vf = new VideoFrame(frameData.data, {
84
+ format: 'BGRA',
85
+ codedWidth: frameData.width,
86
+ codedHeight: frameData.height,
87
+ timestamp: frameData.timestamp,
88
+ });
89
+ yield this.writer.write(vf);
90
+ }
91
+ catch (error) {
92
+ console.error('VideoRender.drawImage error:', error);
93
+ }
94
+ });
95
+ }
96
+ bind(element) {
97
+ this.element = element;
98
+ if (this.element.firstChild) {
99
+ this.element.removeChild(this.element.firstChild);
100
+ }
101
+ this.element.appendChild(this.video);
102
+ this.video.srcObject = new MediaStream([this.track]);
103
+ }
104
+ unbind() {
105
+ if (this.element.firstChild) {
106
+ this.element.removeChild(this.element.firstChild);
107
+ }
108
+ this.element = null;
109
+ }
110
+ setContentMode(mode) {
111
+ this.contentMode = mode;
112
+ }
113
+ }
114
+ exports.default = BGRAVideoRenderer;
@@ -24,7 +24,7 @@ class Canvas3DRGBARenderer {
24
24
  1, 1, 0.0,
25
25
  -1, 1, 0.0
26
26
  ];
27
- this.vertexIndices = [
27
+ this.vertexIndice = [
28
28
  0, 1, 2,
29
29
  0, 2, 3
30
30
  ];
@@ -37,7 +37,7 @@ class Canvas3DRGBARenderer {
37
37
  }
38
38
  _initGL() {
39
39
  try {
40
- this.gl = this.canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });
40
+ this.gl = this.canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false }); //|| canvas.getContext("experimental-webgl", { antialias: false });
41
41
  }
42
42
  catch (e) {
43
43
  return false;
@@ -103,21 +103,22 @@ class Canvas3DRGBARenderer {
103
103
  _initTexture() {
104
104
  this.texture = this.gl.createTexture();
105
105
  this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
106
- // this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);
106
+ // c++ addon 层拷贝数据时翻转,这里不做翻转
107
+ this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);
107
108
  this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
108
109
  this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
109
110
  this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
110
111
  this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
111
112
  }
112
- _initTextureAttribute() {
113
+ _initTextureAttr() {
113
114
  // vertex data
114
115
  const vertexBuffer = this.gl.createBuffer();
115
116
  this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
116
117
  this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.vertex), this.gl.STATIC_DRAW);
117
- // indices data
118
- const vertexIndicesBuffer = this.gl.createBuffer();
119
- this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, vertexIndicesBuffer);
120
- this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.vertexIndices), this.gl.STATIC_DRAW);
118
+ // indice data
119
+ const vertexIndiceBuffer = this.gl.createBuffer();
120
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, vertexIndiceBuffer);
121
+ this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.vertexIndice), this.gl.STATIC_DRAW);
121
122
  // set position attribute
122
123
  const aVertexPosition = this.gl.getAttribLocation(this.glProgram, 'aPos');
123
124
  this.gl.vertexAttribPointer(aVertexPosition, 3, this.gl.FLOAT, false, 0, 0);
@@ -142,8 +143,7 @@ class Canvas3DRGBARenderer {
142
143
  height: '100%',
143
144
  display: 'flex',
144
145
  justifyContent: 'center',
145
- alignItems: 'center',
146
- willChange: 'transform',
146
+ alignItems: 'center'
147
147
  });
148
148
  this.container = container;
149
149
  element.appendChild(this.container);
@@ -169,7 +169,7 @@ class Canvas3DRGBARenderer {
169
169
  }
170
170
  } while (false);
171
171
  if (ret) {
172
- this._initTextureAttribute();
172
+ this._initTextureAttr();
173
173
  this._initTexture();
174
174
  }
175
175
  }
@@ -202,7 +202,7 @@ class Canvas3DRGBARenderer {
202
202
  const { width, height, transform } = calcCanvasStyle(options);
203
203
  this.canvas.width = width;
204
204
  this.canvas.height = height;
205
- this.canvas.style.transform = `${transform} rotateX(180deg)`;
205
+ this.canvas.style.transform = transform;
206
206
  }
207
207
  drawFrame(imageData) {
208
208
  if (!this.ready) {
@@ -226,7 +226,7 @@ class Canvas3DRGBARenderer {
226
226
  });
227
227
  try {
228
228
  this.gl.viewport(0, 0, contentWidth, contentHeight);
229
- this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, contentWidth, contentHeight, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, imageData.data // .slice(0) new Uint8Array(imageData.data)
229
+ this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, contentWidth, contentHeight, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, imageData.data // new Uint8Array(imageData.data)
230
230
  );
231
231
  this.gl.drawElements(this.gl.TRIANGLES, 6, this.gl.UNSIGNED_SHORT, 0);
232
232
  }
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const EventEmitter = require('events').EventEmitter;
13
+ const isEqual = require('lodash.isequal');
14
+ const { calcVideoStyle } = require('../util');
15
+ /* contentMode
16
+ * - 0: Cropped mode. Uniformly scale the video until it fills the visible boundaries (cropped).
17
+ * One dimension of the video may have clipped contents.
18
+ * - 1: Fit mode. Uniformly scale the video until one of its dimension fits the boundary (zoomed to fit).
19
+ * Areas that are not filled due to the disparity in the aspect ratio will be filled with black.
20
+ */
21
+ class I420VideoRenderer {
22
+ constructor() {
23
+ this.cachedOptions = {};
24
+ this.event = new EventEmitter();
25
+ this.element = null;
26
+ this.video = document.createElement('video');
27
+ this.video.setAttribute('style', 'width: 100%; height: 100%; display: block; margin: 0 auto;');
28
+ this.video.setAttribute('autoplay', 'autoplay');
29
+ this.video.muted = true;
30
+ this.contentMode = 1;
31
+ this.ready = false;
32
+ this.track = new MediaStreamTrackGenerator({ kind: 'video' });
33
+ this.writer = this.track.writable.getWriter();
34
+ }
35
+ getView() {
36
+ return this.element;
37
+ }
38
+ _updateStyle(options = {
39
+ contentWidth: 0,
40
+ contentHeight: 0,
41
+ rotation: 0,
42
+ mirrorView: false,
43
+ contentMode: 0,
44
+ containerWidth: 0,
45
+ containerHeight: 0,
46
+ isNeedRotate: true
47
+ }) {
48
+ if (isEqual(this.cachedOptions, options)) {
49
+ return;
50
+ }
51
+ this.cachedOptions = Object.assign({}, options);
52
+ const style = calcVideoStyle(options);
53
+ Object.keys(style).forEach(key => {
54
+ this.video.style[key] = style[key];
55
+ });
56
+ }
57
+ drawFrame(frameData) {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ if (!this.ready) {
60
+ this.ready = true;
61
+ this.event.emit('ready');
62
+ }
63
+ this._updateStyle({
64
+ rotation: frameData.rotation,
65
+ isNeedRotate: frameData.isNeedRotate,
66
+ contentWidth: frameData.width,
67
+ contentHeight: frameData.height,
68
+ contentMode: this.contentMode,
69
+ mirrorView: false,
70
+ containerWidth: this.element.clientWidth,
71
+ containerHeight: this.element.clientHeight,
72
+ });
73
+ if (global.i420Frames) {
74
+ global.i420Frames.push(frameData);
75
+ if (global.i420Frames.length > 100) {
76
+ global.i420Frames.shift();
77
+ }
78
+ }
79
+ else {
80
+ global.i420Frames = [frameData];
81
+ }
82
+ try {
83
+ const vf = new VideoFrame(frameData.data, {
84
+ format: 'I420',
85
+ codedWidth: frameData.width,
86
+ codedHeight: frameData.height,
87
+ timestamp: frameData.timestamp,
88
+ });
89
+ yield this.writer.write(vf);
90
+ // console.debug('VideoRender.drawImage write video frame success');
91
+ }
92
+ catch (error) {
93
+ console.error('VideoRender.drawImage error:', error);
94
+ }
95
+ });
96
+ }
97
+ bind(element) {
98
+ this.element = element;
99
+ if (this.element.firstChild) {
100
+ this.element.removeChild(this.element.firstChild);
101
+ }
102
+ this.element.appendChild(this.video);
103
+ this.video.srcObject = new MediaStream([this.track]);
104
+ }
105
+ unbind() {
106
+ if (this.element.firstChild) {
107
+ this.element.removeChild(this.element.firstChild);
108
+ }
109
+ this.element = null;
110
+ }
111
+ setContentMode(mode) {
112
+ this.contentMode = mode;
113
+ }
114
+ }
115
+ exports.default = I420VideoRenderer;
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const EventEmitter = require('events').EventEmitter;
13
+ const isEqual = require('lodash.isequal');
14
+ const { calcVideoStyle } = require('../util');
15
+ /* contentMode
16
+ * - 0: Cropped mode. Uniformly scale the video until it fills the visible boundaries (cropped).
17
+ * One dimension of the video may have clipped contents.
18
+ * - 1: Fit mode. Uniformly scale the video until one of its dimension fits the boundary (zoomed to fit).
19
+ * Areas that are not filled due to the disparity in the aspect ratio will be filled with black.
20
+ */
21
+ class RGBAVideoRenderer {
22
+ constructor() {
23
+ this.cachedOptions = {};
24
+ this.event = new EventEmitter();
25
+ this.element = null;
26
+ this.video = document.createElement('video');
27
+ this.video.setAttribute('style', 'width: 100%; height: 100%; display: block; margin: 0 auto;');
28
+ this.video.setAttribute('autoplay', 'autoplay');
29
+ this.video.muted = true;
30
+ this.contentMode = 1;
31
+ this.ready = false;
32
+ this.track = new MediaStreamTrackGenerator({ kind: 'video' });
33
+ this.writer = this.track.writable.getWriter();
34
+ }
35
+ getView() {
36
+ return this.element;
37
+ }
38
+ _updateStyle(options = {
39
+ contentWidth: 0,
40
+ contentHeight: 0,
41
+ rotation: 0,
42
+ mirrorView: false,
43
+ contentMode: 0,
44
+ containerWidth: 0,
45
+ containerHeight: 0,
46
+ isNeedRotate: true
47
+ }) {
48
+ if (isEqual(this.cachedOptions, options)) {
49
+ return;
50
+ }
51
+ this.cachedOptions = Object.assign({}, options);
52
+ const style = calcVideoStyle(options);
53
+ Object.keys(style).forEach(key => {
54
+ this.video.style[key] = style[key];
55
+ });
56
+ }
57
+ drawFrame(frameData) {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ if (!this.ready) {
60
+ this.ready = true;
61
+ this.event.emit('ready');
62
+ }
63
+ this._updateStyle({
64
+ rotation: frameData.rotation,
65
+ isNeedRotate: frameData.isNeedRotate,
66
+ contentWidth: frameData.width,
67
+ contentHeight: frameData.height,
68
+ contentMode: this.contentMode,
69
+ mirrorView: false,
70
+ containerWidth: this.element.clientWidth,
71
+ containerHeight: this.element.clientHeight,
72
+ });
73
+ if (global.rgbaFrames) {
74
+ global.rgbaFrames.push(frameData);
75
+ if (global.rgbaFrames.length > 100) {
76
+ global.rgbaFrames.shift();
77
+ }
78
+ }
79
+ else {
80
+ global.rgbaFrames = [frameData];
81
+ }
82
+ try {
83
+ const vf = new VideoFrame(frameData.data, {
84
+ format: 'RGBA',
85
+ codedWidth: frameData.width,
86
+ codedHeight: frameData.height,
87
+ timestamp: frameData.timestamp,
88
+ });
89
+ yield this.writer.write(vf);
90
+ // console.debug('VideoRender.drawImage write video frame success');
91
+ }
92
+ catch (error) {
93
+ console.error('VideoRender.drawImage error:', error);
94
+ }
95
+ });
96
+ }
97
+ bind(element) {
98
+ this.element = element;
99
+ if (this.element.firstChild) {
100
+ this.element.removeChild(this.element.firstChild);
101
+ }
102
+ this.element.appendChild(this.video);
103
+ this.video.srcObject = new MediaStream([this.track]);
104
+ }
105
+ unbind() {
106
+ if (this.element.firstChild) {
107
+ this.element.removeChild(this.element.firstChild);
108
+ }
109
+ this.element = null;
110
+ }
111
+ setContentMode(mode) {
112
+ this.contentMode = mode;
113
+ }
114
+ }
115
+ exports.default = RGBAVideoRenderer;
@@ -92,7 +92,7 @@ class RGBRenderer {
92
92
  containerHeight: this.container.clientHeight,
93
93
  isNeedRotate
94
94
  });
95
- let newImage = new ImageData(new Uint8ClampedArray(imageData.data.slice(0)), width, height);
95
+ let newImage = new ImageData(new Uint8ClampedArray(imageData.data.buffer || imageData.data), width, height);
96
96
  const tempCanvas = document.createElement('canvas');
97
97
  tempCanvas.width = imageData.width;
98
98
  tempCanvas.height = imageData.height;
@@ -50,6 +50,9 @@ declare const _default: {
50
50
  GlRenderer: typeof GlRenderer;
51
51
  SoftwareRenderer: any;
52
52
  RGBRenderer: any;
53
+ I420VideoRenderer: any;
54
+ BGRAVideoRenderer: any;
55
+ RGBAVideoRenderer: any;
53
56
  Canvas3DRGBARenderer: any;
54
57
  };
55
58
  export default _default;
@@ -9,6 +9,9 @@ const GlRenderer_1 = __importDefault(require("./GlRenderer"));
9
9
  const SoftwareRenderer_1 = __importDefault(require("./SoftwareRenderer"));
10
10
  // @ts-ignore
11
11
  const RGBRenderer_1 = __importDefault(require("./RGBRenderer"));
12
+ const I420VideoRenderer_1 = __importDefault(require("./I420VideoRenderer"));
13
+ const BGRAVideoRenderer_1 = __importDefault(require("./BGRAVideoRenderer"));
14
+ const RGBAVideoRenderer_1 = __importDefault(require("./RGBAVideoRenderer"));
12
15
  const Canvas3DRGBARenderer_1 = __importDefault(require("./Canvas3DRGBARenderer"));
13
16
  class GlRenderer {
14
17
  constructor() {
@@ -53,5 +56,8 @@ exports.default = {
53
56
  GlRenderer,
54
57
  SoftwareRenderer: SoftwareRenderer_1.default,
55
58
  RGBRenderer: RGBRenderer_1.default,
59
+ I420VideoRenderer: I420VideoRenderer_1.default,
60
+ BGRAVideoRenderer: BGRAVideoRenderer_1.default,
61
+ RGBAVideoRenderer: RGBAVideoRenderer_1.default,
56
62
  Canvas3DRGBARenderer: Canvas3DRGBARenderer_1.default,
57
63
  };
@@ -16,7 +16,6 @@ export declare class Config {
16
16
  setDebugMode(enable: boolean): void;
17
17
  getDebugMode(): boolean;
18
18
  }
19
- export declare const config: Config;
20
19
  export declare function isNeedKeepWidthAndHeight(rotation: number, isNeedRotate: boolean): boolean;
21
20
  export declare function calcScaleRate(vertical: boolean, contentMode: number, contentWidth: number, contentHeight: number, containerWidth: number, containerHeight: number): number;
22
21
  export declare function calcCanvasStyle(options?: {
@@ -31,4 +30,17 @@ export declare function calcCanvasStyle(options?: {
31
30
  }): {
32
31
  [x: string]: any;
33
32
  };
33
+ export declare function calcVideoStyle(options?: {
34
+ contentWidth: number;
35
+ contentHeight: number;
36
+ rotation: number;
37
+ mirrorView: boolean;
38
+ contentMode: number;
39
+ containerWidth: number;
40
+ containerHeight: number;
41
+ isNeedRotate: boolean;
42
+ }): {
43
+ [x: string]: any;
44
+ };
45
+ export declare const config: Config;
34
46
  export declare function allocBuffer(length: number, userId?: string, streamType?: TRTCVideoStreamType): Buffer;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.allocBuffer = exports.calcCanvasStyle = exports.calcScaleRate = exports.isNeedKeepWidthAndHeight = exports.config = exports.Config = void 0;
3
+ exports.allocBuffer = exports.config = exports.calcVideoStyle = exports.calcCanvasStyle = exports.calcScaleRate = exports.isNeedKeepWidthAndHeight = exports.Config = void 0;
4
4
  /**
5
5
  * 配置对象, 可用来打开 debug 模式
6
6
  *
@@ -23,7 +23,6 @@ class Config {
23
23
  }
24
24
  }
25
25
  exports.Config = Config;
26
- exports.config = new Config();
27
26
  function isNeedKeepWidthAndHeight(rotation, isNeedRotate) {
28
27
  // 需保持宽高不做变化
29
28
  return rotation === 0 || rotation === 180 || !isNeedRotate;
@@ -92,6 +91,42 @@ function calcCanvasStyle(options = {
92
91
  return style;
93
92
  }
94
93
  exports.calcCanvasStyle = calcCanvasStyle;
94
+ function calcVideoStyle(options = {
95
+ contentWidth: 0,
96
+ contentHeight: 0,
97
+ rotation: 0,
98
+ mirrorView: false,
99
+ contentMode: 0,
100
+ containerWidth: 0,
101
+ containerHeight: 0,
102
+ isNeedRotate: true
103
+ }) {
104
+ if ([0, 90, 180, 270].indexOf(options.rotation) === -1) {
105
+ throw new Error('Invalid value for rotation. Only support 0, 90, 180, 270');
106
+ }
107
+ let width = 0;
108
+ let height = 0;
109
+ const isKeepWidthHeight = isNeedKeepWidthAndHeight(options.rotation, options.isNeedRotate);
110
+ if (isNeedKeepWidthAndHeight(options.rotation, options.isNeedRotate)) {
111
+ width = options.contentWidth;
112
+ height = options.contentHeight;
113
+ }
114
+ else {
115
+ height = options.contentWidth;
116
+ width = options.contentHeight;
117
+ }
118
+ const scale = calcScaleRate(!isKeepWidthHeight, options.contentMode, width, height, options.containerWidth, options.containerHeight);
119
+ const style = {
120
+ width: `${width * scale}px`,
121
+ height: `${height * scale}px`,
122
+ };
123
+ if (options.mirrorView) {
124
+ style.transform = 'rotateY(180deg)';
125
+ }
126
+ return style;
127
+ }
128
+ exports.calcVideoStyle = calcVideoStyle;
129
+ exports.config = new Config();
95
130
  function allocBuffer(length, userId, streamType) {
96
131
  console.debug('trtc:alloc buffer:', length, userId, streamType);
97
132
  if (length >= 1) {
package/liteav/trtc.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from 'events';
3
- import { AudioMusicParam, Rect, TRTCAppScene, TRTCAudioEffectParam, TRTCAudioQuality, TRTCBeautyStyle, TRTCDeviceState, TRTCDeviceType, TRTCLogLevel, TRTCRenderParams, TRTCRoleType, TRTCSwitchRoomParam, TRTCVideoBufferType, TRTCVideoFillMode, TRTCVideoFrame, TRTCVideoPixelFormat, TRTCVideoRotation, TRTCVideoStreamType, TRTCWaterMarkSrcType, PluginInfo, TRTCAudioRecordingParams, TRTCScreenCaptureSourceInfo, TRTCScreenCaptureProperty } from './trtc_define';
3
+ import { AudioMusicParam, Rect, TRTCAppScene, TRTCAudioEffectParam, TRTCAudioQuality, TRTCBeautyStyle, TRTCDeviceState, TRTCDeviceType, TRTCLogLevel, TRTCRenderParams, TRTCRoleType, TRTCSwitchRoomParam, TRTCVideoBufferType, TRTCVideoFillMode, TRTCVideoFrame, TRTCVideoPixelFormat, TRTCVideoRotation, TRTCVideoStreamType, TRTCWaterMarkSrcType, PluginInfo, TRTCAudioRecordingParams, TRTCScreenCaptureSourceInfo, TRTCScreenCaptureProperty, TRTCSpeedTestParams } from './trtc_define';
4
4
  export * from './trtc_define';
5
5
  export * from './trtc_code';
6
6
  /**
@@ -337,6 +337,15 @@ declare class TRTCCloud extends EventEmitter {
337
337
  * @param {Number} totalCount - 需要测速的服务器总数量
338
338
  */
339
339
  bindOnSpeedTest(): void;
340
+ /**
341
+ * 5.5 网速测试的结果回调
342
+ *
343
+ * 该统计回调由 startSpeedTest 触发。
344
+ *
345
+ * @event TRTCCallback#onSpeedTestResult
346
+ * @param {TRTCSpeedTestResult} result 网速测试数据数据,包括丢包、往返延迟、上下行的带宽速率。
347
+ */
348
+ bindOnSpeedTestResult(): void;
340
349
  /**
341
350
  * 6.1 摄像头准备就绪
342
351
  *
@@ -1787,13 +1796,6 @@ declare class TRTCCloud extends EventEmitter {
1787
1796
  * @param {Number} volume - 音量大小,100为正常音量,取值范围为0 - 100;默认值:100
1788
1797
  */
1789
1798
  setMusicPublishVolume(id: number, volume: number): void;
1790
- /**
1791
- * 11.22 调整背景音乐的变速效果
1792
- *
1793
- * @param {Number} id - 音乐 ID
1794
- * @param {Number} speedRate - 速度,默认值是1.0f,范围是:[0.5 ~ 2] 之间的浮点数;
1795
- */
1796
- setMusicSpeedRate(id: number, speedRate: number): void;
1797
1799
  /**
1798
1800
  * 12.1 废弃接口: 播放音效
1799
1801
  *
@@ -1864,13 +1866,21 @@ declare class TRTCCloud extends EventEmitter {
1864
1866
  * 测速结果将会用于优化 SDK 接下来的服务器选择策略,因此推荐您在用户首次通话前先进行一次测速,这将有助于我们选择最佳的服务器。
1865
1867
  * 同时,如果测试结果非常不理想,您可以通过醒目的 UI 提示用户选择更好的网络。
1866
1868
  *
1867
- * 注意:测速本身会消耗一定的流量,所以也会产生少量额外的流量费用。
1869
+ * 注意:
1870
+ * 1. 测速过程将产生少量的基础服务费用,详见 [计费概述 > 基础服务](https://cloud.tencent.com/document/product/647/17157#.E5.9F.BA.E7.A1.80.E6.9C.8D.E5.8A.A1) 文档说明。
1871
+ * 2. 请在进入房间前进行网速测试,在房间中网速测试会影响正常的音视频传输效果,而且由于干扰过多,网速测试结果也不准确。
1872
+ * 3. 同一时间只允许一项网速测试任务运行。
1873
+ *
1874
+ * @param {TRTCSpeedTestParams} params - 测速参数
1875
+ * @param {Number} params.sdkAppId - 应用标识
1876
+ * @param {String} params.userId - 用户标识
1877
+ * @param {String} params.userSig - 用户签名
1878
+ * @param {Number} params.expectedUpBandwidth - 预期的上行带宽(kbps,取值范围: 10 ~ 5000,为 0 时不测试)。
1879
+ * @param {Number} params.expectedDownBandwidth - 预期的下行带宽(kbps,取值范围: 10 ~ 5000,为 0 时不测试)。
1868
1880
  *
1869
- * @param {Number} sdkAppId - 应用标识
1870
- * @param {String} userId - 用户标识
1871
- * @param {String} userSig - 用户签名
1881
+ * @return 接口调用结果,< 0:失败
1872
1882
  */
1873
- startSpeedTest(sdkAppId: number, userId: string, userSig: string): void;
1883
+ startSpeedTest(params: TRTCSpeedTestParams | number, userId?: string, userSig?: string): any;
1874
1884
  /**
1875
1885
  * 13.2 停止网络测速
1876
1886
  */
@@ -1986,10 +1996,8 @@ declare class TRTCCloud extends EventEmitter {
1986
1996
  /**
1987
1997
  * 选择绘制的模式 (webgl/yuvcanvs/)
1988
1998
  * @param {Number} mode -
1989
- * - 1 YUV WebGL
1990
- * - 2 YUV Canvas 2D
1991
- * - 3 RGBA Canvas 2D
1992
- * - 4 RGBA WebGL
1999
+ * - 1 webgl
2000
+ * - 2 yuvcanvs
1993
2001
  */
1994
2002
  setRenderMode(mode?: number): void;
1995
2003
  initPluginManager(): void;