yjz-web-sdk 1.0.10 → 1.0.11-beta.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 (61) hide show
  1. package/lib/components/RemotePlayer/index.vue.d.ts +1 -73
  2. package/lib/composables/useCursorStyle.d.ts +1 -1
  3. package/lib/composables/useKeyboardControl.d.ts +1 -1
  4. package/lib/composables/useMouseTouchControl.d.ts +4 -4
  5. package/lib/composables/useRemoteVideo.d.ts +8 -25
  6. package/lib/composables/useResizeObserver.d.ts +1 -1
  7. package/lib/core/data/WebRtcError.d.ts +1 -2
  8. package/lib/core/data/WebrtcDataType.d.ts +1 -11
  9. package/lib/core/groupctrl/SdkController.d.ts +2 -2
  10. package/lib/core/rtc/WebRTCClient.d.ts +2 -5
  11. package/lib/core/rtc/WebRTCConfig.d.ts +1 -1
  12. package/lib/core/rtc/WebRtcNegotiate.d.ts +2 -2
  13. package/lib/core/signal/SignalingClient.d.ts +1 -1
  14. package/lib/core/util/TurnTestUtil.d.ts +2 -2
  15. package/lib/yjz-web-sdk.js +496 -1236
  16. package/package.json +5 -16
  17. package/lib/components/RemotePlayer/type.d.ts +0 -9
  18. package/lib/core/util/MapCache.d.ts +0 -20
  19. package/lib/render/Canvas2DRenderer.d.ts +0 -10
  20. package/lib/render/WebGLRenderer.d.ts +0 -16
  21. package/lib/render/WebGPURenderer.d.ts +0 -18
  22. package/lib/types/index.d.ts +0 -13
  23. package/lib/util/WasmUtil.d.ts +0 -17
  24. package/lib/worker/worker.d.ts +0 -1
  25. package/src/assets/icon/circle.svg +0 -1
  26. package/src/assets/icon/triangle.svg +0 -1
  27. package/src/assets/wasm/h264-atomic.wasm +0 -0
  28. package/src/assets/wasm/h264-simd.wasm +0 -0
  29. package/src/components/RemotePlayer/index.vue +0 -170
  30. package/src/components/RemotePlayer/type.ts +0 -11
  31. package/src/composables/useCursorStyle.ts +0 -15
  32. package/src/composables/useKeyboardControl.ts +0 -32
  33. package/src/composables/useMouseTouchControl.ts +0 -158
  34. package/src/composables/useRemoteVideo.ts +0 -248
  35. package/src/composables/useResizeObserver.ts +0 -27
  36. package/src/core/WebRTCSdk.ts +0 -561
  37. package/src/core/data/MessageType.ts +0 -70
  38. package/src/core/data/TurnType.ts +0 -25
  39. package/src/core/data/WebRtcError.ts +0 -93
  40. package/src/core/data/WebrtcDataType.ts +0 -354
  41. package/src/core/groupctrl/GroupCtrlSocketManager.ts +0 -94
  42. package/src/core/groupctrl/SdkController.ts +0 -96
  43. package/src/core/rtc/WebRTCClient.ts +0 -862
  44. package/src/core/rtc/WebRTCConfig.ts +0 -86
  45. package/src/core/rtc/WebRtcNegotiate.ts +0 -164
  46. package/src/core/signal/SignalingClient.ts +0 -221
  47. package/src/core/util/FileTypeUtils.ts +0 -75
  48. package/src/core/util/KeyCodeUtil.ts +0 -162
  49. package/src/core/util/Logger.ts +0 -83
  50. package/src/core/util/MapCache.ts +0 -135
  51. package/src/core/util/ScreenControlUtil.ts +0 -174
  52. package/src/core/util/TurnTestUtil.ts +0 -123
  53. package/src/env.d.ts +0 -30
  54. package/src/index.ts +0 -61
  55. package/src/render/Canvas2DRenderer.ts +0 -38
  56. package/src/render/WebGLRenderer.ts +0 -150
  57. package/src/render/WebGPURenderer.ts +0 -194
  58. package/src/types/index.ts +0 -15
  59. package/src/types/webgpu.d.ts +0 -1158
  60. package/src/util/WasmUtil.ts +0 -291
  61. package/src/worker/worker.ts +0 -292
@@ -1,291 +0,0 @@
1
- import { AVCodecID } from "@libmedia/avutil";
2
- import { base64 } from '@libmedia/common'
3
- import wasmUrl from '../assets/wasm/h264-simd.wasm?url'
4
- import atoWasmUrl from '../assets/wasm/h264-atomic.wasm?url'
5
- import {DecoderSupportResult, RendererType, RenderingCapabilities} from "../types";
6
-
7
- const supportAtomic = WebAssembly.validate(base64.base64ToUint8Array('AGFzbQEAAAABBgFgAX8BfwISAQNlbnYGbWVtb3J5AgMBgIACAwIBAAcJAQVsb2FkOAAACgoBCAAgAP4SAAAL'))
8
- const supportSimd = WebAssembly.validate(base64.base64ToUint8Array('AGFzbQEAAAABBQFgAAF7AhIBA2VudgZtZW1vcnkCAwGAgAIDAgEACgoBCABBAP0ABAAL'))
9
-
10
-
11
- export function getWasm(codecId?: AVCodecID): string {
12
- switch (codecId) {
13
- // H264
14
- case AVCodecID.AV_CODEC_ID_H264:
15
- if(supportSimd){
16
- return wasmUrl
17
- } else if(supportAtomic){
18
- return atoWasmUrl
19
- } else {
20
- return ''
21
- }
22
- default:
23
- return ''
24
- }
25
- }
26
-
27
- // 定义视频编码类型枚举
28
- export enum VideoCodecType {
29
- H264 = 'h264',
30
- H265 = 'h265',
31
- VP8 = 'vp8',
32
- VP9 = 'vp9',
33
- AV1 = 'av1',
34
- }
35
-
36
- // 对应 WebCodecs codec 字符串
37
- const CodecStringMap: Record<VideoCodecType, string> = {
38
- [VideoCodecType.H264]: 'avc1.42E01E', // baseline profile
39
- [VideoCodecType.H265]: 'hvc1.1.6.L93.B0', // HEVC main profile
40
- [VideoCodecType.VP8]: 'vp8',
41
- [VideoCodecType.VP9]: 'vp09.00.10.08',
42
- [VideoCodecType.AV1]: 'av01.0.04M.08',
43
- };
44
-
45
-
46
- export async function checkDecoderSupport(codec: VideoCodecType): Promise<DecoderSupportResult> {
47
- if (typeof VideoDecoder === 'undefined' || !VideoDecoder.isConfigSupported) {
48
- return { supported: false, hardware: false, software: false };
49
- }
50
-
51
- const baseConfig = {
52
- codec: CodecStringMap[codec],
53
- codedWidth: 720,
54
- codedHeight: 1280
55
- };
56
-
57
- let supported = false;
58
- let hardware = false;
59
- let software = false;
60
-
61
- // 基础能力检测
62
- try {
63
- const basic = await VideoDecoder.isConfigSupported(baseConfig as any);
64
- supported = basic.supported === true;
65
- } catch {}
66
-
67
- if (!supported) {
68
- return { supported: false, hardware: false, software: false };
69
- }
70
-
71
- // 测试硬件解码
72
- try {
73
- const hard = await VideoDecoder.isConfigSupported({
74
- ...baseConfig,
75
- hardwareAcceleration: "prefer-hardware",
76
- } as any);
77
-
78
- if (hard.supported) {
79
- hardware = true;
80
- }
81
- } catch {}
82
-
83
- // 测试软件解码
84
- try {
85
- const soft = await VideoDecoder.isConfigSupported({
86
- ...baseConfig,
87
- hardwareAcceleration: "prefer-software",
88
- } as any);
89
-
90
- if (soft.supported) {
91
- software = true;
92
- }
93
- } catch {}
94
-
95
- // Safari fallback(支持 HEVC 但不返回 hardware/software)
96
- if (!hardware && !software) {
97
- const isSafari =
98
- /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
99
- if (isSafari) {
100
- software = true;
101
- }
102
- }
103
-
104
- return { supported, hardware, software };
105
- }
106
-
107
-
108
-
109
- // 检查 VideoEncoder 支持
110
- export async function isEncoderSupported(codec: VideoCodecType): Promise<boolean> {
111
- if (typeof VideoEncoder === 'undefined' || !VideoEncoder.isConfigSupported) return false;
112
-
113
- try {
114
- const support = await (VideoEncoder as any).isConfigSupported({
115
- codec: CodecStringMap[codec],
116
- width: 640,
117
- height: 480,
118
- });
119
- return support.supported;
120
- } catch {
121
- return false;
122
- }
123
- }
124
-
125
- /**
126
- * 是否为移动端(基本所有移动端 WebGPU 都不稳定,直接禁用)
127
- */
128
- const isMobileDevice = (): boolean => {
129
- if (typeof navigator === 'undefined') return true
130
- return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS|OPiOS/i.test(
131
- navigator.userAgent
132
- )
133
- }
134
-
135
- /* ==================== 1. WebGPU ==================== */
136
- let _webgpuChecked = false
137
- let _webgpuSupported = false
138
-
139
- export const isWebGPUSupported = async (): Promise<boolean> => {
140
- // 已经检测过直接返回缓存
141
- if (_webgpuChecked) return _webgpuSupported
142
-
143
- // 移动端直接否
144
- if (isMobileDevice()) {
145
- _webgpuSupported = false
146
- _webgpuChecked = true
147
- return false
148
- }
149
-
150
- // 基础 API 检查
151
- if (!('gpu' in navigator) || typeof navigator.gpu?.requestAdapter !== 'function') {
152
- _webgpuSupported = false
153
- _webgpuChecked = true
154
- return false
155
- }
156
-
157
- try {
158
- // 真正尝试获取 adapter —— 这是唯一 100% 可靠的方式
159
- const adapter = await navigator.gpu.requestAdapter()
160
- _webgpuSupported = !!adapter
161
- } catch (e) {
162
- // 任何异常(驱动黑名单、权限、Secure Context 等)都视为不支持
163
- console.warn('[WebGPU] detection failed:', e)
164
- _webgpuSupported = false
165
- } finally {
166
- _webgpuChecked = true
167
- }
168
-
169
- return _webgpuSupported
170
- }
171
-
172
- /* ==================== 2. WebGL2 ==================== */
173
- let _webgl2Checked = false
174
- let _webgl2Supported = false
175
-
176
- export const isWebGL2Supported = (canvas?: HTMLCanvasElement): boolean => {
177
- if (_webgl2Checked) return _webgl2Supported
178
-
179
- const testCanvas = canvas ?? document.createElement('canvas')
180
-
181
- // 某些浏览器即使有 WebGL2,也会在隐私模式/低电量模式下返回 null
182
- const contextNames: string[] = ['webgl2', 'experimental-webgl2']
183
- let gl: WebGL2RenderingContext | null = null
184
-
185
- for (const name of contextNames) {
186
- try {
187
- gl = testCanvas.getContext(name) as WebGL2RenderingContext | null
188
- if (gl) break
189
- } catch (_) {
190
- // ignore
191
- }
192
- }
193
-
194
- _webgl2Supported = !!gl
195
- _webgl2Checked = true
196
- return _webgl2Supported
197
- }
198
-
199
- /* ==================== 3. WebGL1 ==================== */
200
- let _webgl1Checked = false
201
- let _webgl1Supported = false
202
-
203
- export const isWebGL1Supported = (canvas?: HTMLCanvasElement): boolean => {
204
- if (_webgl1Checked) return _webgl1Supported
205
-
206
- const testCanvas = canvas ?? document.createElement('canvas')
207
-
208
- // 兼容老的 experimental-webgl
209
- const contextNames: string[] = [
210
- 'webgl',
211
- 'experimental-webgl',
212
- 'webkit-3d',
213
- 'moz-webgl',
214
- ]
215
-
216
- let gl: WebGLRenderingContext | null = null
217
- for (const name of contextNames) {
218
- try {
219
- gl = testCanvas.getContext(name) as WebGLRenderingContext | null
220
- if (gl) break
221
- } catch (_) {}
222
- }
223
-
224
- // 额外检查:某些浏览器会返回 context 但实际被禁用(返回黑色画面)
225
- if (gl) {
226
- const debugInfo = gl.getExtension('WEBGL_debug_renderer_info')
227
- if (debugInfo) {
228
- const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
229
- if (renderer && /llvmpipe|software/i.test(renderer)) {
230
- // 软件渲染器,通常性能极差,建议当做不支持
231
- gl = null
232
- }
233
- }
234
- }
235
-
236
- _webgl1Supported = !!gl
237
- _webgl1Checked = true
238
- return _webgl1Supported
239
- }
240
-
241
- /* ==================== 4. Canvas 2D ==================== */
242
- let _canvas2dChecked = false
243
- let _canvas2dSupported = false
244
-
245
- export const isCanvas2DSupported = (canvas?: HTMLCanvasElement): boolean => {
246
- if (_canvas2dChecked) return _canvas2dSupported
247
-
248
- const testCanvas = canvas ?? document.createElement('canvas')
249
- let ctx: CanvasRenderingContext2D | null = null
250
-
251
- try {
252
- ctx = testCanvas.getContext('2d', {
253
- // 防止某些极端隐私模式下返回 null
254
- alpha: true,
255
- desynchronized: false,
256
- })
257
- } catch (_) {
258
- ctx = null
259
- }
260
-
261
- // 极少数浏览器会返回 ctx 但实际被禁用
262
- if (ctx && typeof ctx.fillRect === 'function') {
263
- _canvas2dSupported = true
264
- } else {
265
- _canvas2dSupported = false
266
- }
267
-
268
- _canvas2dChecked = true
269
- return _canvas2dSupported
270
- }
271
-
272
- /* ==================== 统一检测入口(推荐在程序启动时调用一次)=================== */
273
- export const detectRenderingCapabilities = async (): Promise<RenderingCapabilities> => {
274
- const [webgpu, webgl2, webgl1, canvas2d] = await Promise.all([
275
- isWebGPUSupported(),
276
- Promise.resolve(isWebGL2Supported()),
277
- Promise.resolve(isWebGL1Supported()),
278
- Promise.resolve(isCanvas2DSupported()),
279
- ]);
280
-
281
- // 按优先级选择最佳渲染方式
282
- const best: RendererType =
283
- (webgpu && 'webgpu') ||
284
- (webgl2 && 'webgl2') ||
285
- (webgl1 && 'webgl1') ||
286
- (canvas2d && 'canvas2d') ||
287
- 'none';
288
-
289
- return { webgpu, webgl2, webgl1, canvas2d, best };
290
- }
291
-
@@ -1,292 +0,0 @@
1
- import { WebVideoDecoder, WasmVideoDecoder } from "@libmedia/avcodec";
2
- import {
3
- addAVPacketData,
4
- AVCodecID,
5
- AVCodecParameters,
6
- avMalloc, AVPacket, AVPacketFlags,
7
- compileResource, createAVPacket, destroyAVFrame, destroyAVPacket
8
- } from "@libmedia/avutil";
9
- import { WebGLRenderer } from "../render/WebGLRenderer";
10
- import { WebGPURenderer } from "../render/WebGPURenderer";
11
- import { Canvas2DRenderer } from "../render/Canvas2DRenderer";
12
- import { RenderMode, WebGLDefault8Render, WebGPUDefault8Render } from "@libmedia/avrender";
13
- import { memcpyFromUint8Array } from "@libmedia/cheap";
14
- import { RendererType } from "../types";
15
- import { getWasm } from "../util/WasmUtil";
16
-
17
- interface WorkerState {
18
- supportH265: boolean;
19
- isHardware: boolean;
20
- isSoftware: boolean;
21
- decoderReady: boolean;
22
- webDecoder: WebVideoDecoder | null;
23
- wasmDecoder: WasmVideoDecoder | null;
24
- avPacket: pointer<AVPacket> | null;
25
- webRenderer: WebGLRenderer | WebGPURenderer | Canvas2DRenderer | null;
26
- wasmRenderer: WebGLDefault8Render | WebGPUDefault8Render | null;
27
- renderType: RenderMode | null;
28
- }
29
-
30
- const state: WorkerState = {
31
- supportH265: false,
32
- isHardware: false,
33
- isSoftware: false,
34
- decoderReady: false,
35
- webDecoder: null,
36
- wasmDecoder: null,
37
- avPacket: null,
38
- webRenderer: null,
39
- wasmRenderer: null,
40
- renderType: null
41
- };
42
-
43
- // -------- pendingFrames 队列管理 --------
44
- const MAX_PENDING_FRAMES = 100;
45
- const PENDING_FRAMES_TIMEOUT = 5000; // 5 秒
46
- const pendingFrames: any[] = [];
47
- let pendingFramesTimer: number | null = null;
48
-
49
- function startPendingFramesTimer() {
50
- if (pendingFramesTimer) return;
51
- pendingFramesTimer = setTimeout(() => {
52
- pendingFrames.length = 0;
53
- pendingFramesTimer = null;
54
- console.warn("[Worker] pendingFrames cleared due to timeout");
55
- }, PENDING_FRAMES_TIMEOUT);
56
- }
57
-
58
- function resetPendingFramesTimer() {
59
- if (pendingFramesTimer) {
60
- clearTimeout(pendingFramesTimer);
61
- pendingFramesTimer = null;
62
- }
63
- }
64
-
65
- function enqueueFrame(frame: any) {
66
- if (pendingFrames.length >= MAX_PENDING_FRAMES) pendingFrames.shift(); // 丢弃最老帧
67
- pendingFrames.push(frame);
68
- startPendingFramesTimer();
69
- }
70
-
71
- function flushPendingFrames() {
72
- resetPendingFramesTimer();
73
- while (pendingFrames.length) {
74
- handleDecode(pendingFrames.shift());
75
- }
76
- }
77
-
78
- function clearPendingFrames() {
79
- pendingFrames.length = 0;
80
- resetPendingFramesTimer();
81
- }
82
-
83
- // -------- 初始化解码器 --------
84
- async function initWasmDecoder() {
85
- if (state.wasmDecoder) return;
86
- const codecpar = make<AVCodecParameters>();
87
- codecpar.codecId = AVCodecID.AV_CODEC_ID_H264;
88
-
89
- state.wasmDecoder = new WasmVideoDecoder({
90
- resource: await compileResource(getWasm(codecpar.codecId), true),
91
- onReceiveAVFrame: frame => {
92
- state.wasmRenderer?.render(frame);
93
- destroyAVFrame(frame);
94
- }
95
- });
96
-
97
- const ret = await state.wasmDecoder.open(addressof(codecpar));
98
- if (ret) {
99
- state.decoderReady = false;
100
- clearPendingFrames();
101
- self.postMessage({ type: 'decoderError', error: 'WasmDecoder初始化失败' });
102
- } else {
103
- console.log('初始化成功 WasmVideoDecoder');
104
- state.decoderReady = true;
105
- flushPendingFrames();
106
- }
107
- }
108
-
109
- async function initWebDecoder(isHardware: boolean) {
110
- if (state.webDecoder) return;
111
- const codecpar = make<AVCodecParameters>();
112
- codecpar.codecId = AVCodecID.AV_CODEC_ID_H264;
113
-
114
- state.webDecoder = new WebVideoDecoder({
115
- codec: 'avc1.42E01E',
116
- onReceiveVideoFrame: frame => state.webRenderer?.render(frame),
117
- onError: error => console.error(`[WebDecoder] decode error: ${error}`),
118
- enableHardwareAcceleration: isHardware,
119
- optimizeForLatency: true,
120
- });
121
-
122
- const ret = await state.webDecoder.open(addressof(codecpar));
123
- if (ret) {
124
- state.decoderReady = false;
125
- clearPendingFrames();
126
- self.postMessage({ type: 'decoderError', error: 'WebDecoder初始化失败' });
127
- } else {
128
- console.log('初始化成功 WebVideoDecoder');
129
- state.decoderReady = true;
130
- self.postMessage({ type: 'initSuccess' });
131
- flushPendingFrames();
132
- }
133
- }
134
-
135
- // -------- 初始化渲染器 --------
136
- function initWebRenderer(canvas: OffscreenCanvas, renderType: RendererType) {
137
- if (state.webRenderer) return;
138
- try {
139
- switch (renderType) {
140
- case 'webgpu':
141
- state.webRenderer = new WebGPURenderer(canvas);
142
- break
143
- case 'webgl2':
144
- state.webRenderer = new WebGLRenderer('webgl2', canvas);
145
- break;
146
- case 'webgl1':
147
- state.webRenderer = new WebGLRenderer('webgl', canvas);
148
- break;
149
- case 'canvas2d':
150
- state.webRenderer = new Canvas2DRenderer(canvas);
151
- break;
152
- default:
153
- throw new Error(`Unsupported render type: ${renderType}`);
154
- }
155
- } catch (err) {
156
- self.postMessage({ type: 'rendererError', error: 'webRenderer初始化失败' });
157
- }
158
- }
159
-
160
- async function initWasmRender(canvas: OffscreenCanvas, pixelRatio: number, renderType: RendererType) {
161
- if (state.wasmRenderer) return;
162
- try {
163
- switch (renderType) {
164
- case 'webgpu':
165
- state.wasmRenderer = new WebGPUDefault8Render(canvas, { renderMode: RenderMode.FIT, devicePixelRatio: 1 });
166
- break
167
- case 'webgl2':
168
- case 'webgl1':
169
- state.wasmRenderer = new WebGLDefault8Render(canvas, { renderMode: RenderMode.FIT, devicePixelRatio: 1 });
170
- break;
171
- default:
172
- throw new Error(`Unsupported WASM render type: ${renderType}`);
173
- }
174
- await state.wasmRenderer.init();
175
- state.wasmRenderer.viewport(canvas.width, canvas.height);
176
- } catch (err) {
177
- self.postMessage({ type: 'rendererError', error: 'wasmRenderer初始化失败' });
178
- }
179
- }
180
-
181
- // -------- 清理函数 --------
182
- function clearCanvas(renderer: any) {
183
- if (!renderer) return;
184
- if ('clear' in renderer) {
185
- renderer.clear();
186
- } else if (renderer.canvas) {
187
- const ctx = renderer.canvas.getContext('2d') as OffscreenCanvasRenderingContext2D | null;
188
- ctx?.clearRect(0, 0, renderer.canvas.width, renderer.canvas.height);
189
- }
190
- }
191
-
192
- function clearRender() {
193
- if (state.avPacket) {
194
- destroyAVPacket(state.avPacket);
195
- state.avPacket = createAVPacket();
196
- }
197
- clearCanvas(state.webRenderer);
198
- clearCanvas(state.wasmRenderer);
199
- }
200
-
201
- async function stopDecoding() {
202
- clearRender();
203
- if (state.avPacket) {
204
- destroyAVPacket(state.avPacket);
205
- state.avPacket = null;
206
- }
207
- state.webRenderer?.destroy?.();
208
- state.webRenderer = null;
209
- state.wasmRenderer?.destroy?.();
210
- state.wasmRenderer = null;
211
-
212
- if (state.webDecoder) {
213
- await state.webDecoder.flush();
214
- state.webDecoder.close();
215
- state.webDecoder = null;
216
- }
217
- if (state.wasmDecoder) {
218
- await state.wasmDecoder.flush();
219
- state.wasmDecoder.close();
220
- state.wasmDecoder = null;
221
- }
222
- state.decoderReady = false;
223
- clearPendingFrames();
224
- self.close();
225
- }
226
-
227
- // -------- 统一解码函数 --------
228
- async function handleDecode(frame: any) {
229
- if (!state.decoderReady || !state.avPacket) {
230
- enqueueFrame(frame);
231
- return;
232
- }
233
-
234
- resetPendingFramesTimer();
235
-
236
- const dataP: pointer<uint8> = avMalloc(frame.data.length);
237
- memcpyFromUint8Array(dataP, frame.data.length, frame.data);
238
- addAVPacketData(state.avPacket, dataP, frame.data.length);
239
- state.avPacket.dts = state.avPacket.pts = BigInt(Math.round(performance.now() * 1000));
240
- if (frame.label === 'key') state.avPacket.flags |= AVPacketFlags.AV_PKT_FLAG_KEY;
241
- let ret
242
- if (state.supportH265 && (state.isHardware || state.isSoftware)) {
243
- ret = state.webDecoder?.decode(state.avPacket);
244
- if(ret){
245
- console.log(`webDecoder decode===>fail ${ret}`)
246
- }else{
247
- console.log(`webDecoder decode===>success ${ret}`)
248
- }
249
- } else {
250
- ret = state.wasmDecoder?.decode(state.avPacket);
251
- if(ret){
252
- console.log(`wasmDecoder decode===>fail ${ret}`)
253
- }else{
254
- console.log(`wasmDecoder decode===>success ${ret}`)
255
- }
256
- }
257
- }
258
-
259
- // -------- Worker 消息处理 --------
260
- self.onmessage = async (e: MessageEvent) => {
261
- const { type, ...data } = e.data;
262
- switch (type) {
263
- case 'init':
264
- state.supportH265 = data.supportH265;
265
- state.isHardware = data.isHardware;
266
- state.avPacket = createAVPacket();
267
-
268
- if (state.supportH265 && (state.isHardware || state.isSoftware)) {
269
- await initWebDecoder(state.isHardware);
270
- initWebRenderer(data.canvas, data.renderType);
271
- } else {
272
- await initWasmDecoder();
273
- await initWasmRender(data.canvas, data.pixelRatio, data.renderType);
274
- }
275
- break;
276
-
277
- case 'decode':
278
- await handleDecode(data);
279
- break;
280
-
281
- case 'stopDecode':
282
- await stopDecoding();
283
- break;
284
-
285
- case 'clearRender':
286
- clearRender();
287
- break;
288
-
289
- default:
290
- console.warn("[Worker] Unknown message type:", type);
291
- }
292
- };