@xmov/avatar 2.4.0 → 2.5.0-alpha.1

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.
Files changed (157) hide show
  1. package/README.md +34 -6
  2. package/package-dist/agent/avatar.cjs +1 -0
  3. package/package-dist/agent/avatar.modern.js +1 -0
  4. package/package-dist/agent/avatar.module.js +1 -0
  5. package/package-dist/agent/avatar.umd.js +1 -0
  6. package/package-dist/agent/index.d.ts +42 -0
  7. package/{dist/agent/types.d.ts → package-dist/agent/public-types.d.ts} +115 -116
  8. package/package-dist/index.cjs +3 -0
  9. package/package-dist/index.d.ts +34 -0
  10. package/package-dist/index.modern.js +1 -0
  11. package/package-dist/index.module.js +1 -0
  12. package/package-dist/index.umd.js +14 -0
  13. package/package-dist/public-types.d.ts +205 -0
  14. package/package.json +41 -33
  15. package/dist/agent/avatar.cjs +0 -1
  16. package/dist/agent/avatar.modern.js +0 -1
  17. package/dist/agent/avatar.module.js +0 -1
  18. package/dist/agent/avatar.umd.js +0 -1
  19. package/dist/agent/index.d.ts +0 -137
  20. package/dist/baseRender/AudioRenderer.d.ts +0 -46
  21. package/dist/baseRender/AudioWorklet.d.ts +0 -78
  22. package/dist/baseRender/AvatarRenderer.d.ts +0 -225
  23. package/dist/baseRender/MSEAudioPlayer.d.ts +0 -51
  24. package/dist/baseRender/UIRenderer.d.ts +0 -39
  25. package/dist/baseRender/pcm-audio-processor.d.ts +0 -63
  26. package/dist/control/APIForwarder.d.ts +0 -23
  27. package/dist/control/DataCacheQueue.d.ts +0 -69
  28. package/dist/control/EventDispatcher.d.ts +0 -35
  29. package/dist/control/RenderScheduler.d.ts +0 -171
  30. package/dist/control/SaveAndDownload.d.ts +0 -14
  31. package/dist/control/StreamingClient.d.ts +0 -33
  32. package/dist/control/VideoPlayer.d.ts +0 -47
  33. package/dist/control/ttsa.d.ts +0 -125
  34. package/dist/encoding/media-recorder-encoder.d.ts +0 -33
  35. package/dist/encoding/pcm-webm-encoder.d.ts +0 -13
  36. package/dist/encoding/webcodec-opus-encoder.d.ts +0 -41
  37. package/dist/encoding/webm-muxer.d.ts +0 -90
  38. package/dist/index.cjs +0 -2
  39. package/dist/index.cjs.map +0 -1
  40. package/dist/index.d.ts +0 -251
  41. package/dist/index.modern.js +0 -2
  42. package/dist/index.modern.js.map +0 -1
  43. package/dist/index.module.js +0 -2
  44. package/dist/index.module.js.map +0 -1
  45. package/dist/index.umd.js +0 -2
  46. package/dist/index.umd.js.map +0 -1
  47. package/dist/modules/Composition.d.ts +0 -28
  48. package/dist/modules/ResourceManager.d.ts +0 -299
  49. package/dist/modules/TrackRenderer/base-track.d.ts +0 -4
  50. package/dist/modules/TrackRenderer/index.d.ts +0 -12
  51. package/dist/modules/TrackRenderer/render-implements.d.ts +0 -19
  52. package/dist/modules/TrackRenderer/track-pic.d.ts +0 -8
  53. package/dist/modules/TrackRenderer/track-subtitle.d.ts +0 -8
  54. package/dist/modules/cache-manager.d.ts +0 -5
  55. package/dist/modules/decoder.d.ts +0 -84
  56. package/dist/modules/error-handle.d.ts +0 -17
  57. package/dist/modules/network.d.ts +0 -21
  58. package/dist/modules/sentry-reporter.d.ts +0 -58
  59. package/dist/proto/face_data_pb.d.ts +0 -0
  60. package/dist/types/capability.d.ts +0 -15
  61. package/dist/types/error.d.ts +0 -70
  62. package/dist/types/event.d.ts +0 -25
  63. package/dist/types/frame-data.d.ts +0 -107
  64. package/dist/types/index.d.ts +0 -196
  65. package/dist/types/render.d.ts +0 -18
  66. package/dist/utils/DataInterface.d.ts +0 -113
  67. package/dist/utils/GLDevice.d.ts +0 -46
  68. package/dist/utils/GLPipeline.d.ts +0 -84
  69. package/dist/utils/GLPipelineDebugTools.d.ts +0 -5
  70. package/dist/utils/Math.d.ts +0 -21
  71. package/dist/utils/__tests__/capability-checker.test.d.ts +0 -1
  72. package/dist/utils/audio-session.d.ts +0 -11
  73. package/dist/utils/audio.d.ts +0 -1
  74. package/dist/utils/capability-checker.d.ts +0 -28
  75. package/dist/utils/encodeToken.d.ts +0 -14
  76. package/dist/utils/face.d.ts +0 -1
  77. package/dist/utils/float32-decoder.d.ts +0 -26
  78. package/dist/utils/fpsTracker.d.ts +0 -27
  79. package/dist/utils/index.d.ts +0 -22
  80. package/dist/utils/logger.d.ts +0 -9
  81. package/dist/utils/media-recorder-timestamp.d.ts +0 -15
  82. package/dist/utils/pcmAnalyzer.d.ts +0 -40
  83. package/dist/utils/perfermance.d.ts +0 -15
  84. package/dist/utils/request.d.ts +0 -20
  85. package/dist/utils/requestAnimateFrames.d.ts +0 -31
  86. package/dist/utils/time.d.ts +0 -9
  87. package/dist/utils/video-probe-asset.d.ts +0 -28
  88. package/dist/view/DebugOverlay.d.ts +0 -54
  89. package/dist/worker/streaming-video.d.ts +0 -1
  90. package/src/baseRender/AudioRenderer.ts +0 -328
  91. package/src/baseRender/AudioWorklet.ts +0 -776
  92. package/src/baseRender/AvatarRenderer.ts +0 -1550
  93. package/src/baseRender/MSEAudioPlayer.ts +0 -254
  94. package/src/baseRender/UIRenderer.ts +0 -195
  95. package/src/baseRender/pcm-audio-processor.js +0 -267
  96. package/src/control/APIForwarder.ts +0 -67
  97. package/src/control/DataCacheQueue.ts +0 -372
  98. package/src/control/EventDispatcher.ts +0 -106
  99. package/src/control/RenderScheduler.ts +0 -1000
  100. package/src/control/SaveAndDownload.js +0 -77
  101. package/src/control/StreamingClient.ts +0 -138
  102. package/src/control/VideoPlayer.ts +0 -306
  103. package/src/control/ttsa.ts +0 -754
  104. package/src/encoding/media-recorder-encoder.ts +0 -175
  105. package/src/encoding/pcm-webm-encoder.ts +0 -72
  106. package/src/encoding/webcodec-opus-encoder.ts +0 -258
  107. package/src/encoding/webm-muxer.ts +0 -337
  108. package/src/global.d.ts +0 -112
  109. package/src/index.ts +0 -2053
  110. package/src/modules/Composition.ts +0 -79
  111. package/src/modules/ResourceManager.ts +0 -926
  112. package/src/modules/TrackRenderer/base-track.ts +0 -7
  113. package/src/modules/TrackRenderer/index.ts +0 -40
  114. package/src/modules/TrackRenderer/render-implements.ts +0 -269
  115. package/src/modules/TrackRenderer/track-pic.ts +0 -19
  116. package/src/modules/TrackRenderer/track-subtitle.ts +0 -16
  117. package/src/modules/cache-manager.ts +0 -10
  118. package/src/modules/decoder.ts +0 -548
  119. package/src/modules/error-handle.ts +0 -20
  120. package/src/modules/network.ts +0 -71
  121. package/src/modules/sentry-reporter.ts +0 -171
  122. package/src/proto/face_data.proto +0 -45
  123. package/src/proto/face_data_pb.js +0 -1297
  124. package/src/proto/protobuf.min.js +0 -8
  125. package/src/types/capability.ts +0 -24
  126. package/src/types/error.ts +0 -211
  127. package/src/types/event.ts +0 -38
  128. package/src/types/frame-data.ts +0 -121
  129. package/src/types/index.ts +0 -220
  130. package/src/types/render.ts +0 -18
  131. package/src/utils/DataInterface.ts +0 -746
  132. package/src/utils/GLDevice.ts +0 -286
  133. package/src/utils/GLPipeline.ts +0 -1293
  134. package/src/utils/GLPipelineDebugTools.ts +0 -174
  135. package/src/utils/Math.ts +0 -266
  136. package/src/utils/__tests__/capability-checker.test.ts +0 -159
  137. package/src/utils/audio-session.ts +0 -144
  138. package/src/utils/audio.ts +0 -44
  139. package/src/utils/blueimp-md5.d.ts +0 -3
  140. package/src/utils/capability-checker.ts +0 -762
  141. package/src/utils/encodeToken.ts +0 -115
  142. package/src/utils/face.ts +0 -29
  143. package/src/utils/float32-decoder.js +0 -130
  144. package/src/utils/fpsTracker.ts +0 -100
  145. package/src/utils/index.ts +0 -182
  146. package/src/utils/logger.js +0 -36
  147. package/src/utils/media-recorder-timestamp.ts +0 -79
  148. package/src/utils/pcmAnalyzer.ts +0 -154
  149. package/src/utils/perfermance.ts +0 -141
  150. package/src/utils/request.ts +0 -107
  151. package/src/utils/requestAnimateFrames.ts +0 -195
  152. package/src/utils/time.ts +0 -32
  153. package/src/utils/video-probe-asset.ts +0 -99
  154. package/src/view/DebugOverlay.ts +0 -409
  155. package/src/worker/streaming-video.ts +0 -4647
  156. /package/{dist → package-dist}/agent/index.cjs +0 -0
  157. /package/{dist → package-dist}/agent/index.umd.js +0 -0
@@ -1,286 +0,0 @@
1
- // @ts-nocheck
2
-
3
- export class GLDevice {
4
- private _ElementTypeMap_JS2GL!: { readonly [index: string]: number };
5
- private _FormatTypeMap_Ext2Int!: Map<number, Map<number, number>>;
6
- private _FormatTypeMap_Ext2Str!: Map<number, string>;
7
- private shaderStage!: { readonly [index: string]: number };
8
- private running: boolean = true;
9
- private syncMedia: HTMLVideoElement | null = null;
10
- private syncMediaTime: DOMHighResTimeStamp | null = null;
11
- private _lost_context_sim: WEBGL_lose_context | null = null;
12
- canvas: HTMLCanvasElement;
13
- gl!: WebGL2RenderingContext;
14
- frameID: number | null;
15
- cbRender: (device: GLDevice) => void;
16
- private _isDestroyed: boolean = false;
17
- private _onContextLost: (e: Event) => void;
18
- private _onContextRestored: () => void;
19
- private _onContextCreationError: (e: Event) => void;
20
-
21
- constructor(canvas: HTMLCanvasElement) {
22
- this.canvas = canvas;
23
- this.frameID = null;
24
-
25
- const initContext = () => {
26
- const gl = this.canvas.getContext('webgl2', { antialias: false, premultipliedAlpha: true, preserveDrawingBuffer: true });
27
- if (!gl) throw Error("WebGL context cannot be created."); else this.gl = gl;
28
-
29
- this._lost_context_sim = this.gl.getExtension("WEBGL_lose_context");
30
-
31
- this.shaderStage = {
32
- "vertex": this.gl.VERTEX_SHADER,
33
- "fragment": this.gl.FRAGMENT_SHADER
34
- }
35
-
36
- this._ElementTypeMap_JS2GL = {
37
- "Uint8Array": this.gl.UNSIGNED_BYTE,
38
- "Uint8ClampedArray": this.gl.UNSIGNED_BYTE,
39
- "Int8Array": this.gl.BYTE,
40
- "Uint16Array": this.gl.UNSIGNED_SHORT,
41
- "Int16Array": this.gl.SHORT,
42
- "Uint32Array": this.gl.UNSIGNED_INT,
43
- "Int32Array": this.gl.INT,
44
- "Float16Array": this.gl.HALF_FLOAT,
45
- "Float32Array": this.gl.FLOAT
46
- };
47
-
48
- const _FormatTypeMap_Ext2Int_Raw: [number, [number, number][]][] = [
49
- [this.gl.UNSIGNED_BYTE, [[this.gl.RED, this.gl.R8], [this.gl.RED_INTEGER, this.gl.R8UI], [this.gl.RG, this.gl.RG8], [this.gl.RG_INTEGER, this.gl.RG8UI], [this.gl.RGB, this.gl.RGB8], [this.gl.RGB_INTEGER, this.gl.RGB8UI], [this.gl.RGBA, this.gl.RGBA8], [this.gl.RGBA_INTEGER, this.gl.RGBA8UI]]],
50
- [this.gl.BYTE, [[this.gl.RED, this.gl.R8_SNORM], [this.gl.RED_INTEGER, this.gl.R8I], [this.gl.RG, this.gl.RG8_SNORM], [this.gl.RG_INTEGER, this.gl.RG8I], [this.gl.RGB, this.gl.RGB8_SNORM], [this.gl.RGB_INTEGER, this.gl.RGB8I], [this.gl.RGBA, this.gl.RGBA8_SNORM], [this.gl.RGBA_INTEGER, this.gl.RGBA8I]]],
51
- [this.gl.UNSIGNED_SHORT, [[this.gl.RED_INTEGER, this.gl.R16UI], [this.gl.RG_INTEGER, this.gl.RG16UI], [this.gl.RGB_INTEGER, this.gl.RGB16UI], [this.gl.RGBA_INTEGER, this.gl.RGBA16UI], [this.gl.DEPTH_COMPONENT, this.gl.DEPTH_COMPONENT16]]],
52
- [this.gl.SHORT, [[this.gl.RED_INTEGER, this.gl.R16I], [this.gl.RG_INTEGER, this.gl.RG16I], [this.gl.RGB_INTEGER, this.gl.RGB16I], [this.gl.RGBA_INTEGER, this.gl.RGBA16I]]],
53
- [this.gl.UNSIGNED_INT, [[this.gl.RED_INTEGER, this.gl.R32UI], [this.gl.RG_INTEGER, this.gl.RG32UI], [this.gl.RGB_INTEGER, this.gl.RGB32UI], [this.gl.RGBA_INTEGER, this.gl.RGBA32UI], [this.gl.DEPTH_COMPONENT, this.gl.DEPTH_COMPONENT24]]],
54
- [this.gl.INT, [[this.gl.RED_INTEGER, this.gl.R32I], [this.gl.RG_INTEGER, this.gl.RG32I], [this.gl.RGB_INTEGER, this.gl.RGB32I], [this.gl.RGBA_INTEGER, this.gl.RGBA32I]]],
55
- [this.gl.HALF_FLOAT, [[this.gl.RED, this.gl.R16F], [this.gl.RG, this.gl.RG16F], [this.gl.RGB, this.gl.RGB16F], [this.gl.RGBA, this.gl.RGBA16F]]],
56
- [this.gl.FLOAT, [[this.gl.RED, this.gl.R32F], [this.gl.RG, this.gl.RG32F], [this.gl.RGB, this.gl.RGB32F], [this.gl.RGBA, this.gl.RGBA32F], [this.gl.DEPTH_COMPONENT, this.gl.DEPTH_COMPONENT32F]]],
57
- [this.gl.UNSIGNED_SHORT_5_6_5, [[this.gl.RGB, this.gl.RGB565]]],
58
- [this.gl.UNSIGNED_SHORT_4_4_4_4, [[this.gl.RGBA, this.gl.RGBA4]]],
59
- [this.gl.UNSIGNED_SHORT_5_5_5_1, [[this.gl.RGBA, this.gl.RGB5_A1]]],
60
- [this.gl.UNSIGNED_INT_2_10_10_10_REV, [[this.gl.RGBA, this.gl.RGB10_A2]]],
61
- [this.gl.UNSIGNED_INT_10F_11F_11F_REV, [[this.gl.RGB, this.gl.R11F_G11F_B10F]]],
62
- [this.gl.UNSIGNED_INT_5_9_9_9_REV, [[this.gl.RGB, this.gl.RGB9_E5]]],
63
- [this.gl.UNSIGNED_INT_24_8, [[this.gl.DEPTH_STENCIL, this.gl.DEPTH24_STENCIL8]]],
64
- [this.gl.FLOAT_32_UNSIGNED_INT_24_8_REV, [[this.gl.DEPTH_STENCIL, this.gl.DEPTH32F_STENCIL8]]]
65
- ];
66
- this._FormatTypeMap_Ext2Int = new Map();
67
- for (const [elemType, formats] of _FormatTypeMap_Ext2Int_Raw) {
68
- const formatMap = new Map<number, number>();
69
- for (const [extFormat, intFormat] of formats) formatMap.set(extFormat, intFormat);
70
- this._FormatTypeMap_Ext2Int.set(elemType, formatMap);
71
- }
72
-
73
- const _FormatTypeMap_Ext2Str_Raw: { [name: string]: number } = {
74
- "GL_RED": this.gl.RED,
75
- "GL_RED_INTEGER": this.gl.RED_INTEGER,
76
- "GL_RG": this.gl.RG,
77
- "GL_RG_INTEGER": this.gl.RG_INTEGER,
78
- "GL_RGB": this.gl.RGB,
79
- "GL_RGB_INTEGER": this.gl.RGB_INTEGER,
80
- "GL_RGBA": this.gl.RGBA,
81
- "GL_RGBA_INTEGER": this.gl.RGBA_INTEGER,
82
- "GL_DEPTH_COMPONENT": this.gl.DEPTH_COMPONENT,
83
- "GL_DEPTH_STENCIL": this.gl.DEPTH_STENCIL
84
- }
85
- this._FormatTypeMap_Ext2Str = new Map();
86
- for (const [name, value] of Object.entries(_FormatTypeMap_Ext2Str_Raw)) this._FormatTypeMap_Ext2Str.set(value, name);
87
- };
88
-
89
- this.frameID = null;
90
- this.cbRender = () => { };
91
-
92
- // 使用命名函数引用,以便 destroy() 能正确移除监听器
93
- this._onContextLost = (e: Event) => {
94
- e.preventDefault();
95
- this.stop();
96
- };
97
- this._onContextRestored = initContext;
98
- this._onContextCreationError = (e: Event) => {
99
- console.error((e as WebGLContextEvent).statusMessage || "WebGL context creation error: unknown error.");
100
- };
101
-
102
- this.canvas.addEventListener("webglcontextlost", this._onContextLost, false);
103
- this.canvas.addEventListener("webglcontextrestored", this._onContextRestored, false);
104
- this.canvas.addEventListener("webglcontextcreationerror", this._onContextCreationError, false);
105
-
106
- initContext();
107
- }
108
- compileShaderProgram(shaders: { readonly [index: string]: string }): WebGLProgram {
109
- let shaderProgram = this.gl.createProgram();
110
- if (!shaderProgram) throw new Error('WebGL shader program creation failed.');
111
-
112
- for (const [stage, code] of Object.entries(shaders)) {
113
- const shader = this.gl.createShader(this.shaderStage[stage]);
114
- if (!shader) throw new Error('WebGL shader creation failed.');
115
- this.gl.shaderSource(shader, code)
116
- this.gl.compileShader(shader)
117
- if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
118
- const compile_log = this.gl.getShaderInfoLog(shader);
119
- this.gl.deleteShader(shader);
120
- throw new Error('WebGL shader compile failed:' + compile_log);
121
- }
122
- this.gl.attachShader(shaderProgram, shader);
123
- }
124
-
125
- this.gl.linkProgram(shaderProgram);
126
- if (!this.gl.getProgramParameter(shaderProgram, this.gl.LINK_STATUS)) {
127
- const link_log = this.gl.getProgramInfoLog(shaderProgram);
128
- this.gl.deleteProgram(shaderProgram);
129
- throw new Error('WebGL shader compile failed:' + link_log);
130
- }
131
-
132
- return shaderProgram;
133
- }
134
- getShaderProgramUniformLocation(program: WebGLProgram, attribNames: Array<string>): { [index: string]: WebGLUniformLocation } {
135
- let result: { [index: string]: WebGLUniformLocation } = {};
136
- for (const name of attribNames) result[name] = this.gl.getUniformLocation(program, name)!;
137
- return result;
138
- }
139
- getShaderProgramUniformBlockLocation(program: WebGLProgram, attribNames: Array<string>): { [index: string]: GLint } {
140
- let result: { [index: string]: GLint } = {};
141
- for (const name of attribNames) result[name] = this.gl.getUniformBlockIndex(program, name)!;
142
- return result;
143
- }
144
- getShaderProgramAttribLocation(program: WebGLProgram, attribNames: Array<string>): { [index: string]: GLint } {
145
- let result: { [index: string]: GLint } = {};
146
- for (const name of attribNames) result[name] = this.gl.getAttribLocation(program, name)!;
147
- return result;
148
- }
149
- getGLArrayElementType(arr: ArrayBufferView<ArrayBufferLike>): number | null {
150
- // @ts-ignore
151
- const tag = arr[Symbol.toStringTag] as string;
152
- if (tag in this._ElementTypeMap_JS2GL) return this._ElementTypeMap_JS2GL[tag]; else return null;
153
- }
154
- getGLTexInternalFormat(externalFormat: number, elementType: number): number | null {
155
- const formats = this._FormatTypeMap_Ext2Int.get(elementType);
156
- if (formats) {
157
- const internalFormat = formats.get(externalFormat);
158
- if (internalFormat) return internalFormat;
159
- }
160
- return null;
161
- }
162
- texImage2D(target: number, level: number, width: number, height: number, format: number, srcData: ArrayBufferView<ArrayBufferLike>) {
163
- const elementType = this.getGLArrayElementType(srcData);
164
- // @ts-ignore
165
- if (!elementType) throw new Error(`Unsupported data format: ${srcData[Symbol.toStringTag] as string}`);
166
- const internalFormat = this.getGLTexInternalFormat(format, elementType);
167
- // @ts-ignore
168
- if (!internalFormat) throw new Error(`No available internal format for ${srcData[Symbol.toStringTag] as string} and ${this._FormatTypeMap_Ext2Str.get(format) ?? "unknown"}.`);
169
- if (this.gl.HALF_FLOAT == elementType) srcData = new Uint16Array(srcData.buffer); // patch for Float16Array
170
- this.gl.texImage2D(target, level, internalFormat, width, height, 0, format, elementType, srcData);
171
- }
172
- texImage3D(target: number, level: number, width: number, height: number, depth: number, format: number, srcData: ArrayBufferView<ArrayBufferLike>) {
173
- const elementType = this.getGLArrayElementType(srcData);
174
- // @ts-ignore
175
- if (!elementType) throw new Error('Unsupported data format: ' + srcData[Symbol.toStringTag] as string);
176
- const internalFormat = this.getGLTexInternalFormat(format, elementType);
177
- // @ts-ignore
178
- if (!internalFormat) throw new Error(`No available internal format for ${srcData[Symbol.toStringTag] as string} and ${this._FormatTypeMap_Ext2Str.get(format) ?? "unknown"}.`);
179
- if (this.gl.HALF_FLOAT == elementType) srcData = new Uint16Array(srcData.buffer); // patch for Float16Array
180
- this.gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, elementType, srcData);
181
- }
182
- run(fn: (device: GLDevice) => void, syncMedia?: HTMLVideoElement) {
183
- this.running = true;
184
- this.cbRender = fn;
185
- if (syncMedia && syncMedia instanceof HTMLVideoElement) {
186
- this.syncMedia = syncMedia;
187
- const fnWrapper = (now: DOMHighResTimeStamp, metadata: VideoFrameCallbackMetadata) => {
188
- if (this.running) {
189
- this.syncMediaTime = metadata.mediaTime;
190
- this.cbRender(this);
191
- this.frameID = syncMedia.requestVideoFrameCallback(fnWrapper);
192
- }
193
- };
194
- this.syncMediaTime = syncMedia.currentTime;
195
- this.cbRender(this);
196
- syncMedia.requestVideoFrameCallback(fnWrapper);
197
- }
198
- else {
199
- const fnWrapper = () => {
200
- if (this.running) {
201
- this.cbRender(this);
202
- this.frameID = requestAnimationFrame(fnWrapper);
203
- }
204
- };
205
- fnWrapper();
206
- }
207
- }
208
- refresh() { this.cbRender(this); }
209
- getSyncMediaTime(): number | null { return this.syncMediaTime; }
210
- stop() {
211
- if (null !== this.frameID) {
212
- if (this.syncMedia) {
213
- this.syncMedia.cancelVideoFrameCallback(this.frameID);
214
- this.syncMedia = null;
215
- this.syncMediaTime = null;
216
- }
217
- else cancelAnimationFrame(this.frameID);
218
- this.frameID = null;
219
- }
220
- this.running = false;
221
- }
222
- simulateContextFault(contextAvailable: boolean) {
223
- if (this._lost_context_sim) {
224
- contextAvailable ? this._lost_context_sim.restoreContext() : this._lost_context_sim.loseContext();
225
- }
226
- }
227
- captureFrame() {
228
- const width = this.canvas.width
229
- const height = this.canvas.height
230
- const pixelData = new Uint8ClampedArray(width * height * 4)
231
- this.gl.readPixels(0, 0, width, height, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixelData);
232
-
233
- return {
234
- width,
235
- height,
236
- data: pixelData
237
- }
238
- }
239
- destroy(): void {
240
- // 1. 防止重复销毁
241
- if (this._isDestroyed || !this.gl) {
242
- return;
243
- }
244
-
245
- const gl = this.gl;
246
-
247
- try {
248
- // 主动丢失WebGL上下文(关键:通知浏览器回收上下文)
249
- const loseExtension = gl.getExtension("WEBGL_lose_context");
250
- if (loseExtension) {
251
- loseExtension.loseContext(); // 触发上下文丢失,释放浏览器级资源
252
- }
253
-
254
- // 清理画布状态
255
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
256
- gl.flush(); // 确保所有渲染命令执行完毕
257
-
258
- // 清除DOM/引用(助力垃圾回收)
259
- if (this.canvas) {
260
- // 可选:从DOM移除画布(根据业务需求决定是否保留)
261
- // this.canvas.remove();
262
- // 清空画布内容
263
- const ctx2d = this.canvas.getContext("2d");
264
- if (ctx2d) {
265
- ctx2d.clearRect(0, 0, this.canvas.width, this.canvas.height);
266
- }
267
- }
268
-
269
- // 移除事件监听器(使用命名函数引用,可正确移除)
270
- if (this.canvas) {
271
- this.canvas.removeEventListener("webglcontextlost", this._onContextLost, false);
272
- this.canvas.removeEventListener("webglcontextrestored", this._onContextRestored, false);
273
- this.canvas.removeEventListener("webglcontextcreationerror", this._onContextCreationError, false);
274
- }
275
-
276
- // 标记上下文为null,防止后续误调用
277
- this.gl = null;
278
- this._isDestroyed = true;
279
-
280
- } catch (error) {
281
- // 即使出错,也标记为销毁(避免重复尝试)
282
- this._isDestroyed = true;
283
- }
284
- }
285
-
286
- }