@vunk/plus 1.7.3 → 1.7.5
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/components/broadcasting-markdown/index.mjs +101 -238
- package/components/broadcasting-markdown/src/ctx.d.ts +1 -4
- package/components/broadcasting-markdown/src/howler-speech.vue.d.ts +49 -88
- package/components/broadcasting-markdown/src/index.vue.d.ts +44 -103
- package/components/broadcasting-markdown/src/types.d.ts +1 -1
- package/components/broadcasting-markdown/src/use.d.ts +6 -8
- package/components/bubble-templates/index.css +4 -0
- package/components/bubble-templates/index.mjs +7 -11412
- package/components/metahuman-broadcasting/index.mjs +8 -5
- package/components/metahuman-broadcasting/src/index.vue.d.ts +62 -114
- package/components/pixi-frame/src/apng.vue.d.ts +3 -3
- package/components/pixi-frame/src/bitmap.vue.d.ts +5 -5
- package/components/pixi-frame/src/core.vue.d.ts +5 -5
- package/components/pixi-frame/src/index.vue.d.ts +12 -12
- package/components/pixi-frame/src/video.vue.d.ts +3 -3
- package/components/typing-markdown/index.mjs +4 -7
- package/components/vditor/src/ctx.d.ts +1 -1
- package/components/vditor/src/index.vue.d.ts +1 -1
- package/index.css +5 -0
- package/package.json +4 -1
- package/shared/StreamingInferenceService.mjs +4 -1
- package/shared/audioToFrames/index.mjs +2 -5
- package/shared/audioToFrames/src/audio/StreamingFeatureExtractorService.d.ts +20 -4
- package/shared/audioToFrames/src/audio/index.d.ts +0 -2
- package/shared/audioToFrames/src/audio/index.mjs +84 -157
- package/shared/audioToFrames/src/core/constants.d.ts +0 -22
- package/shared/audioToFrames/src/core/index.mjs +16 -2643
- package/shared/audioToFrames/src/core/utils.d.ts +1 -68
- package/shared/audioToFrames/src/inference/StreamingInferenceService.d.ts +43 -0
- package/shared/audioToFrames/src/media/index.d.ts +0 -5
- package/shared/audioToFrames/src/media/index.mjs +180 -610
- package/shared/constants.mjs +1 -12
- package/shared/PredictiveFrameLoader.mjs +0 -367
- package/shared/audioToFrames/src/audio/AudioProcessor.d.ts +0 -25
- package/shared/audioToFrames/src/audio/FeatureExtractorService.d.ts +0 -31
- package/shared/audioToFrames/src/inference/types.d.ts +0 -102
- package/shared/audioToFrames/src/media/ImageBitmapPool.d.ts +0 -63
- package/shared/audioToFrames/src/media/ImageProcessor.d.ts +0 -47
- package/shared/audioToFrames/src/media/PlaybackService.d.ts +0 -56
- package/shared/audioToFrames/src/media/WebGLPlaybackService.d.ts +0 -74
- package/shared/audioToFrames/src/media/WebGLRenderer.d.ts +0 -66
- package/shared/utils.mjs +0 -123
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file 音频特征处理工具
|
|
3
|
-
*
|
|
4
|
-
* 本模块提供了对 `FeatureExtractorService` 提取出的 Fbank 特征进行后续处理的工具函数。
|
|
5
|
-
* 主要功能包括:
|
|
6
|
-
* 1. 提供一个窗口函数 `getAudioWindow` 用于从完整的特征序列中提取上下文窗口。
|
|
7
|
-
*
|
|
8
|
-
* @author Zhonghan Li
|
|
9
|
-
*/
|
|
10
|
-
import { NUM_MEL_BINS, NUM_SEQUENCE_FRAMES } from '../core/constants';
|
|
11
|
-
export { NUM_MEL_BINS, NUM_SEQUENCE_FRAMES };
|
|
12
|
-
/**
|
|
13
|
-
* 从完整的音频特征中提取一个固定大小的上下文窗口。
|
|
14
|
-
*
|
|
15
|
-
* @param allAudioFeatures `FeatureExtractorService` 返回的扁平化特征数组。
|
|
16
|
-
* @param allAudioDims `FeatureExtractorService` 返回的维度数组,形如 `[T_chunks, 4, 80]`。
|
|
17
|
-
* @param centerChunkIndex 窗口中心的块(chunk)索引。
|
|
18
|
-
* @returns 一个新的扁平化 Float32Array,代表 (32, 4, 80) 的窗口数据。
|
|
19
|
-
*/
|
|
20
|
-
export declare function getAudioWindow(allAudioFeatures: Float32Array, allAudioDims: number[], centerChunkIndex: number): Float32Array;
|
|
21
|
-
/**
|
|
22
|
-
* 创建AudioContext的兼容函数,处理Safari的限制。
|
|
23
|
-
* 在Safari中,AudioContext需要在用户交互后才能创建。
|
|
24
|
-
*/
|
|
25
|
-
export declare function createAudioContext(): Promise<AudioContext>;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file FeatureExtractorService.ts
|
|
3
|
-
* 该服务封装了与特征提取 Web Worker 的交互,提供了一个简单的 Promise-based API。
|
|
4
|
-
* @author Zhonghan Li
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* 定义从 Worker 返回的成功消息的载荷结构。
|
|
8
|
-
*/
|
|
9
|
-
export interface FeatureExtractionResult {
|
|
10
|
-
features: Float32Array;
|
|
11
|
-
dimensions: number[];
|
|
12
|
-
}
|
|
13
|
-
export declare class FeatureExtractorService {
|
|
14
|
-
private errorHandler;
|
|
15
|
-
private worker;
|
|
16
|
-
constructor();
|
|
17
|
-
/**
|
|
18
|
-
* 处理 AudioBuffer,在后台线程中提取特征。
|
|
19
|
-
* @param audioBuffer Web Audio API 的 AudioBuffer 对象。
|
|
20
|
-
* @returns 一个 Promise,成功时解析为特征结果,失败时拒绝并返回错误信息。
|
|
21
|
-
*/
|
|
22
|
-
process(audioBuffer: AudioBuffer): Promise<FeatureExtractionResult>;
|
|
23
|
-
/**
|
|
24
|
-
* 创建Worker Promise,直接处理消息传递
|
|
25
|
-
*/
|
|
26
|
-
private createWorkerPromise;
|
|
27
|
-
/**
|
|
28
|
-
* 终止Worker
|
|
29
|
-
*/
|
|
30
|
-
terminate(): void;
|
|
31
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import type { ImageDataResponse } from '../media/DataLoaderService';
|
|
2
|
-
import type { StreamingChunkData } from './StreamingInferenceService';
|
|
3
|
-
/**
|
|
4
|
-
* 初始化Worker,加载ONNX模型
|
|
5
|
-
*/
|
|
6
|
-
export interface StreamingWorkerInitMessage {
|
|
7
|
-
type: 'init';
|
|
8
|
-
modelPath: string;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* 初始化流式推理,加载数据集、图片Blob和混合掩码
|
|
12
|
-
*/
|
|
13
|
-
export interface StreamingWorkerInitStreamingMessage {
|
|
14
|
-
type: 'init_streaming';
|
|
15
|
-
dataset: ImageDataResponse;
|
|
16
|
-
zipBuffer: ArrayBuffer;
|
|
17
|
-
blendingMaskBitmap: ImageBitmap;
|
|
18
|
-
startImageIndex: number;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* 运行单个chunk的推理
|
|
22
|
-
*/
|
|
23
|
-
export interface StreamingWorkerRunMessage {
|
|
24
|
-
type: 'streaming_run';
|
|
25
|
-
chunkData: StreamingChunkData;
|
|
26
|
-
dataset: ImageDataResponse;
|
|
27
|
-
imageBlobs: Map<string, Blob>;
|
|
28
|
-
blendingMaskBitmap: ImageBitmap;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* 通知所有chunk已发送完毕,包含总帧数
|
|
32
|
-
*/
|
|
33
|
-
export interface StreamingWorkerFinishMessage {
|
|
34
|
-
type: 'finish_chunks';
|
|
35
|
-
totalFrames: number;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 停止推理,清理资源
|
|
39
|
-
*/
|
|
40
|
-
export interface StreamingWorkerStopMessage {
|
|
41
|
-
type: 'stop';
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Worker可接收的所有消息类型
|
|
45
|
-
*/
|
|
46
|
-
export type StreamingWorkerMessage = StreamingWorkerInitMessage | StreamingWorkerInitStreamingMessage | StreamingWorkerRunMessage | StreamingWorkerFinishMessage | StreamingWorkerStopMessage;
|
|
47
|
-
/**
|
|
48
|
-
* 主线程接收的单帧推理结果消息
|
|
49
|
-
*/
|
|
50
|
-
export interface MainThreadFrameMessage {
|
|
51
|
-
type: 'frame';
|
|
52
|
-
payload: {
|
|
53
|
-
frame: ImageBitmap;
|
|
54
|
-
frameIndex: number;
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* 主线程接收的chunk完成消息,包含耗时统计
|
|
59
|
-
*/
|
|
60
|
-
export interface MainThreadChunkCompleteMessage {
|
|
61
|
-
type: 'chunk_complete';
|
|
62
|
-
payload: {
|
|
63
|
-
chunkIndex: number;
|
|
64
|
-
timings: Record<string, number>;
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* 主线程接收的进度消息
|
|
69
|
-
*/
|
|
70
|
-
export interface MainThreadProgressMessage {
|
|
71
|
-
type: 'progress';
|
|
72
|
-
payload: {
|
|
73
|
-
processed: number;
|
|
74
|
-
total: number;
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* 主线程接收的全部完成消息,包含总耗时
|
|
79
|
-
*/
|
|
80
|
-
export interface MainThreadAllCompleteMessage {
|
|
81
|
-
type: 'all_complete';
|
|
82
|
-
payload: {
|
|
83
|
-
totalTimings: Record<string, number>;
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* 主线程接收的错误消息
|
|
88
|
-
*/
|
|
89
|
-
export interface MainThreadErrorMessage {
|
|
90
|
-
type: 'error';
|
|
91
|
-
payload: string;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* 主线程接收的Worker就绪消息
|
|
95
|
-
*/
|
|
96
|
-
export interface MainThreadReadyMessage {
|
|
97
|
-
type: 'ready';
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* 主线程可接收的所有消息类型
|
|
101
|
-
*/
|
|
102
|
-
export type MainThreadMessage = MainThreadFrameMessage | MainThreadChunkCompleteMessage | MainThreadProgressMessage | MainThreadAllCompleteMessage | MainThreadErrorMessage | MainThreadReadyMessage;
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file ImageBitmap对象池
|
|
3
|
-
*
|
|
4
|
-
* 复用ImageBitmap对象以减少内存分配和垃圾回收压力
|
|
5
|
-
* 特别适用于高频率的图像处理场景
|
|
6
|
-
*
|
|
7
|
-
* @author Zhonghan Li
|
|
8
|
-
*/
|
|
9
|
-
export interface PooledBitmap {
|
|
10
|
-
bitmap: ImageBitmap;
|
|
11
|
-
width: number;
|
|
12
|
-
height: number;
|
|
13
|
-
inUse: boolean;
|
|
14
|
-
lastUsed: number;
|
|
15
|
-
}
|
|
16
|
-
export declare class ImageBitmapPool {
|
|
17
|
-
private pool;
|
|
18
|
-
private readonly maxPoolSize;
|
|
19
|
-
private readonly maxIdleTime;
|
|
20
|
-
constructor(maxPoolSize?: number, maxIdleTimeMs?: number);
|
|
21
|
-
/**
|
|
22
|
-
* 获取指定尺寸的ImageBitmap(优先从池中获取)
|
|
23
|
-
*/
|
|
24
|
-
acquire(width: number, height: number): Promise<ImageBitmap>;
|
|
25
|
-
/**
|
|
26
|
-
* 释放ImageBitmap回池中
|
|
27
|
-
*/
|
|
28
|
-
release(bitmap: ImageBitmap): void;
|
|
29
|
-
/**
|
|
30
|
-
* 从池中查找匹配尺寸的可用bitmap
|
|
31
|
-
*/
|
|
32
|
-
private findMatchingBitmap;
|
|
33
|
-
/**
|
|
34
|
-
* 创建新的ImageBitmap
|
|
35
|
-
*/
|
|
36
|
-
private createNewBitmap;
|
|
37
|
-
/**
|
|
38
|
-
* 清理空闲时间过长的对象
|
|
39
|
-
*/
|
|
40
|
-
private cleanupIdleObjects;
|
|
41
|
-
/**
|
|
42
|
-
* 强制清理所有对象
|
|
43
|
-
*/
|
|
44
|
-
cleanup(): void;
|
|
45
|
-
/**
|
|
46
|
-
* 获取池统计信息
|
|
47
|
-
*/
|
|
48
|
-
getStats(): {
|
|
49
|
-
poolSize: number;
|
|
50
|
-
maxPoolSize: number;
|
|
51
|
-
inUseCount: number;
|
|
52
|
-
availableCount: number;
|
|
53
|
-
memoryEstimate: string;
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* 预热池:预先创建一些常用尺寸的bitmap
|
|
57
|
-
*/
|
|
58
|
-
warmup(commonSizes?: Array<{
|
|
59
|
-
width: number;
|
|
60
|
-
height: number;
|
|
61
|
-
}>): Promise<void>;
|
|
62
|
-
}
|
|
63
|
-
export declare const globalImageBitmapPool: ImageBitmapPool;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file 图像张量与 Canvas 工具函数
|
|
3
|
-
*
|
|
4
|
-
* 本模块提供了与图像张量相关的常用工具函数,主要包括:
|
|
5
|
-
* 1. 复用模块级 Canvas 以提升图像处理性能。
|
|
6
|
-
* 2. 从 Blob 加载 ONNX 图像张量。
|
|
7
|
-
* 3. 将张量高效转换为 ImageData 以便渲染。
|
|
8
|
-
*
|
|
9
|
-
* @author Zhonghan Li
|
|
10
|
-
*/
|
|
11
|
-
import type JSZip from 'jszip';
|
|
12
|
-
import { Tensor } from 'onnxruntime-web';
|
|
13
|
-
/**
|
|
14
|
-
* 获取一个共享的、模块级的 Canvas 2D 上下文。
|
|
15
|
-
* 避免重复创建 Canvas 元素,提升性能。
|
|
16
|
-
* @param width 画布期望宽度。
|
|
17
|
-
* @param height 画布期望高度。
|
|
18
|
-
* @returns 返回 2D 上下文。
|
|
19
|
-
*/
|
|
20
|
-
export declare function getSharedCanvasContext(width: number, height: number): CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
|
|
21
|
-
/**
|
|
22
|
-
* 计算 Ping-Pong 动画的下一帧状态(索引和方向)。
|
|
23
|
-
*
|
|
24
|
-
* @param currentIndex 当前帧索引。
|
|
25
|
-
* @param numFrames 动画总帧数。
|
|
26
|
-
* @param direction 当前播放方向 (1 为正向, -1 为反向)。
|
|
27
|
-
* @returns 一个包含 { nextIndex, nextDirection } 的对象。
|
|
28
|
-
*/
|
|
29
|
-
export declare function calculatePingPongState(currentIndex: number, numFrames: number, direction: number): {
|
|
30
|
-
nextIndex: number;
|
|
31
|
-
nextDirection: number;
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
|
-
* 从 JSZip 实例中按需加载并解析图像张量。
|
|
35
|
-
* @param tensorFileName 要加载的 .bin 文件的名称。
|
|
36
|
-
* @param zip JSZip 实例。
|
|
37
|
-
* @param cropSize 裁剪尺寸,用于计算正确的边界和内部尺寸。
|
|
38
|
-
* @returns 一个 ONNX Tensor。
|
|
39
|
-
*/
|
|
40
|
-
export declare function loadTensorFromZip(tensorFileName: string, zip: JSZip, cropSize: number): Promise<Tensor>;
|
|
41
|
-
/**
|
|
42
|
-
* 将张量转换为 ImageData 对象,用于高性能渲染。
|
|
43
|
-
* 此函数避免了昂贵的 toDataURL() 调用。
|
|
44
|
-
* @param tensor 具有 [1, 3, H, W] 形状和 BGR 顺序的输入张量。
|
|
45
|
-
* @returns 返回一个可以直接在 Canvas 上使用的 ImageData 对象,若格式不符则返回 null。
|
|
46
|
-
*/
|
|
47
|
-
export declare function convertTensorToImageData(tensor: Tensor): ImageData | null;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file PlaybackService.ts
|
|
3
|
-
* 实时视频播放服务,用于在 Canvas 上渲染由推理服务生成的视频帧。
|
|
4
|
-
* @author Zhonghan Li
|
|
5
|
-
*/
|
|
6
|
-
export declare class PlaybackService {
|
|
7
|
-
private canvas;
|
|
8
|
-
private ctx;
|
|
9
|
-
private audioPlayer;
|
|
10
|
-
private inferenceRunning;
|
|
11
|
-
private animationFrameId;
|
|
12
|
-
private lastFrameTimestamp;
|
|
13
|
-
private onPlaybackEndCallback;
|
|
14
|
-
/** 播放器是否正在播放。 */
|
|
15
|
-
readonly isPlaying: import("vue").Ref<boolean, boolean>;
|
|
16
|
-
/** 当前播放的帧索引。 */
|
|
17
|
-
readonly currentFrameIndex: import("vue").Ref<number, number>;
|
|
18
|
-
/** 已生成的视频帧 ImageBitmap 数组。 */
|
|
19
|
-
readonly generatedFrames: import("vue").ShallowRef<ImageBitmap[], ImageBitmap[]>;
|
|
20
|
-
/**
|
|
21
|
-
* 创建一个新的 PlaybackService 实例。
|
|
22
|
-
* @param canvas 用于渲染视频帧的 HTMLCanvasElement。
|
|
23
|
-
* @param audioPlayer 用于同步播放的 HTMLAudioElement。
|
|
24
|
-
* @param onPlaybackEndCallback 播放完成后的回调函数(支持异步)。
|
|
25
|
-
*/
|
|
26
|
-
constructor(canvas: HTMLCanvasElement, audioPlayer: HTMLAudioElement, onPlaybackEndCallback?: (() => void | Promise<void>) | null);
|
|
27
|
-
/**
|
|
28
|
-
* 设置推理过程是否仍在运行。
|
|
29
|
-
* 这用于确定当所有帧都播放完毕后是否停止播放循环。
|
|
30
|
-
* @param status 推理是否正在运行。
|
|
31
|
-
*/
|
|
32
|
-
setInferenceRunning(status: boolean): void;
|
|
33
|
-
/**
|
|
34
|
-
* 向播放列表添加一帧并触发播放(如果尚未开始)。
|
|
35
|
-
* @param frameBitmap 要添加的视频帧。
|
|
36
|
-
*/
|
|
37
|
-
addFrame(frameBitmap: ImageBitmap): void;
|
|
38
|
-
/**
|
|
39
|
-
* 开始实时播放。
|
|
40
|
-
*/
|
|
41
|
-
start(): void;
|
|
42
|
-
/**
|
|
43
|
-
* 停止实时播放。
|
|
44
|
-
*/
|
|
45
|
-
stop(): void;
|
|
46
|
-
/**
|
|
47
|
-
* 清理所有播放资源,释放内存。
|
|
48
|
-
* 包括停止播放、重置状态和释放 ImageBitmap 对象。
|
|
49
|
-
*/
|
|
50
|
-
cleanup(): void;
|
|
51
|
-
/**
|
|
52
|
-
* 核心播放循环。
|
|
53
|
-
* @param timestamp 当前时间戳。
|
|
54
|
-
*/
|
|
55
|
-
private playbackLoop;
|
|
56
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file WebGLPlaybackService.ts
|
|
3
|
-
* 基于WebGL的高性能视频播放服务,替代传统的Canvas 2D渲染。
|
|
4
|
-
* 提供与PlaybackService相同的API,但使用WebGL进行渲染。
|
|
5
|
-
* @author Zhonghan Li
|
|
6
|
-
*/
|
|
7
|
-
export declare class WebGLPlaybackService {
|
|
8
|
-
private webglRenderer;
|
|
9
|
-
private audioPlayer;
|
|
10
|
-
private inferenceRunning;
|
|
11
|
-
private animationFrameId;
|
|
12
|
-
private lastFrameTimestamp;
|
|
13
|
-
private onPlaybackEndCallback;
|
|
14
|
-
private isWebGLSupported;
|
|
15
|
-
/** 播放器是否正在播放。 */
|
|
16
|
-
readonly isPlaying: import("vue").Ref<boolean, boolean>;
|
|
17
|
-
/** 当前播放的帧索引。 */
|
|
18
|
-
readonly currentFrameIndex: import("vue").Ref<number, number>;
|
|
19
|
-
/** 已生成的视频帧 ImageBitmap 数组。 */
|
|
20
|
-
readonly generatedFrames: import("vue").ShallowRef<ImageBitmap[], ImageBitmap[]>;
|
|
21
|
-
/**
|
|
22
|
-
* 创建一个新的 WebGLPlaybackService 实例。
|
|
23
|
-
* @param canvas 用于渲染视频帧的 HTMLCanvasElement。
|
|
24
|
-
* @param audioPlayer 用于同步播放的 HTMLAudioElement。
|
|
25
|
-
* @param onPlaybackEndCallback 播放完成后的回调函数(支持异步)。
|
|
26
|
-
*/
|
|
27
|
-
constructor(canvas: HTMLCanvasElement, audioPlayer: HTMLAudioElement, onPlaybackEndCallback?: (() => void | Promise<void>) | null);
|
|
28
|
-
/**
|
|
29
|
-
* 初始化WebGL渲染器
|
|
30
|
-
*/
|
|
31
|
-
initialize(): Promise<void>;
|
|
32
|
-
/**
|
|
33
|
-
* 设置推理过程是否仍在运行。
|
|
34
|
-
* 这用于确定当所有帧都播放完毕后是否停止播放循环。
|
|
35
|
-
* @param status 推理是否正在运行。
|
|
36
|
-
*/
|
|
37
|
-
setInferenceRunning(status: boolean): void;
|
|
38
|
-
/**
|
|
39
|
-
* 向播放列表添加一帧并触发播放(如果尚未开始)。
|
|
40
|
-
* @param frameBitmap 要添加的视频帧。
|
|
41
|
-
*/
|
|
42
|
-
addFrame(frameBitmap: ImageBitmap): void;
|
|
43
|
-
/**
|
|
44
|
-
* 开始实时播放。
|
|
45
|
-
*/
|
|
46
|
-
start(): void;
|
|
47
|
-
/**
|
|
48
|
-
* 停止实时播放。
|
|
49
|
-
*/
|
|
50
|
-
stop(): void;
|
|
51
|
-
/**
|
|
52
|
-
* 清理所有播放资源,释放内存。
|
|
53
|
-
* 包括停止播放、重置状态和释放 ImageBitmap 对象。
|
|
54
|
-
*/
|
|
55
|
-
cleanup(): void;
|
|
56
|
-
/**
|
|
57
|
-
* 核心播放循环。
|
|
58
|
-
* @param timestamp 当前时间戳。
|
|
59
|
-
*/
|
|
60
|
-
private playbackLoop;
|
|
61
|
-
/**
|
|
62
|
-
* 检查WebGL是否受支持
|
|
63
|
-
*/
|
|
64
|
-
static isWebGLSupported(): boolean;
|
|
65
|
-
/**
|
|
66
|
-
* 获取WebGL渲染器信息
|
|
67
|
-
*/
|
|
68
|
-
getWebGLInfo(): {
|
|
69
|
-
renderer: string;
|
|
70
|
-
vendor: string;
|
|
71
|
-
version: string;
|
|
72
|
-
maxTextureSize: number;
|
|
73
|
-
} | null;
|
|
74
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file WebGLRenderer.ts
|
|
3
|
-
* WebGL渲染器,提供高性能的图像渲染能力,替代传统的Canvas 2D渲染。
|
|
4
|
-
* 支持纹理缓存、批量渲染和内存优化。
|
|
5
|
-
* @author Zhonghan Li
|
|
6
|
-
*/
|
|
7
|
-
export declare class WebGLRenderer {
|
|
8
|
-
private canvas;
|
|
9
|
-
private gl;
|
|
10
|
-
private program;
|
|
11
|
-
private vertexBuffer;
|
|
12
|
-
private textureCache;
|
|
13
|
-
private maxTextureSize;
|
|
14
|
-
private isInitialized;
|
|
15
|
-
private readonly vertexShaderSource;
|
|
16
|
-
private readonly fragmentShaderSource;
|
|
17
|
-
constructor(canvas: HTMLCanvasElement);
|
|
18
|
-
/**
|
|
19
|
-
* 初始化WebGL渲染器
|
|
20
|
-
*/
|
|
21
|
-
initialize(): Promise<void>;
|
|
22
|
-
/**
|
|
23
|
-
* 渲染ImageBitmap到Canvas
|
|
24
|
-
* @param imageBitmap 要渲染的图像
|
|
25
|
-
* @param frameToRelease (可选) 渲染后要释放的上一帧
|
|
26
|
-
*/
|
|
27
|
-
render(imageBitmap: ImageBitmap, frameToRelease?: ImageBitmap): void;
|
|
28
|
-
/**
|
|
29
|
-
* 清理纹理缓存中的指定ImageBitmap
|
|
30
|
-
* @param imageBitmap 要清理的ImageBitmap
|
|
31
|
-
*/
|
|
32
|
-
clearTexture(imageBitmap: ImageBitmap): void;
|
|
33
|
-
/**
|
|
34
|
-
* 清理所有资源
|
|
35
|
-
*/
|
|
36
|
-
cleanup(): void;
|
|
37
|
-
/**
|
|
38
|
-
* 创建着色器程序
|
|
39
|
-
*/
|
|
40
|
-
private createShaderProgram;
|
|
41
|
-
/**
|
|
42
|
-
* 编译着色器
|
|
43
|
-
*/
|
|
44
|
-
private compileShader;
|
|
45
|
-
/**
|
|
46
|
-
* 设置顶点缓冲区
|
|
47
|
-
*/
|
|
48
|
-
private setupVertexBuffer;
|
|
49
|
-
/**
|
|
50
|
-
* 从ImageBitmap创建WebGL纹理
|
|
51
|
-
*/
|
|
52
|
-
private createTexture;
|
|
53
|
-
/**
|
|
54
|
-
* 检查WebGL是否支持
|
|
55
|
-
*/
|
|
56
|
-
static isSupported(): boolean;
|
|
57
|
-
/**
|
|
58
|
-
* 获取WebGL信息
|
|
59
|
-
*/
|
|
60
|
-
getInfo(): {
|
|
61
|
-
renderer: string;
|
|
62
|
-
vendor: string;
|
|
63
|
-
version: string;
|
|
64
|
-
maxTextureSize: number;
|
|
65
|
-
};
|
|
66
|
-
}
|
package/shared/utils.mjs
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
class PerformanceTimer {
|
|
2
|
-
constructor() {
|
|
3
|
-
this.timings = {};
|
|
4
|
-
this.startTimes = {};
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* 开始计时
|
|
8
|
-
* @param name 计时器名称
|
|
9
|
-
*/
|
|
10
|
-
start(name) {
|
|
11
|
-
this.startTimes[name] = performance.now();
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* 结束计时并记录
|
|
15
|
-
* @param name 计时器名称
|
|
16
|
-
* @returns 耗时(毫秒)
|
|
17
|
-
*/
|
|
18
|
-
end(name) {
|
|
19
|
-
const startTime = this.startTimes[name];
|
|
20
|
-
if (startTime === void 0) {
|
|
21
|
-
console.warn(`Timer "${name}" was not started`);
|
|
22
|
-
return 0;
|
|
23
|
-
}
|
|
24
|
-
const elapsed = performance.now() - startTime;
|
|
25
|
-
this.timings[name] = elapsed;
|
|
26
|
-
delete this.startTimes[name];
|
|
27
|
-
return elapsed;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* 获取所有计时结果
|
|
31
|
-
* @returns 计时结果对象
|
|
32
|
-
*/
|
|
33
|
-
getTimings() {
|
|
34
|
-
return { ...this.timings };
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* 重置所有计时器
|
|
38
|
-
*/
|
|
39
|
-
reset() {
|
|
40
|
-
this.timings = {};
|
|
41
|
-
this.startTimes = {};
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* 累加计时结果
|
|
45
|
-
* @param name 计时器名称
|
|
46
|
-
* @param value 要累加的值
|
|
47
|
-
*/
|
|
48
|
-
accumulate(name, value) {
|
|
49
|
-
this.timings[name] = (this.timings[name] || 0) + value;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* 合并其他计时器的结果
|
|
53
|
-
* @param other 其他计时器实例
|
|
54
|
-
*/
|
|
55
|
-
merge(other) {
|
|
56
|
-
const otherTimings = other.getTimings();
|
|
57
|
-
for (const [name, value] of Object.entries(otherTimings)) {
|
|
58
|
-
this.accumulate(name, value);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function measurePerformance(timerName, timer) {
|
|
63
|
-
return function(_target, _propertyKey, descriptor) {
|
|
64
|
-
const originalMethod = descriptor.value;
|
|
65
|
-
descriptor.value = function(...args) {
|
|
66
|
-
timer.start(timerName);
|
|
67
|
-
const result = originalMethod.apply(this, args);
|
|
68
|
-
if (result instanceof Promise) {
|
|
69
|
-
return result.finally(() => {
|
|
70
|
-
timer.end(timerName);
|
|
71
|
-
});
|
|
72
|
-
} else {
|
|
73
|
-
timer.end(timerName);
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
return descriptor;
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
function normalizeError(error) {
|
|
81
|
-
if (error instanceof Error) {
|
|
82
|
-
return error.message;
|
|
83
|
-
}
|
|
84
|
-
if (typeof error === "string") {
|
|
85
|
-
return error;
|
|
86
|
-
}
|
|
87
|
-
return "Unknown error occurred";
|
|
88
|
-
}
|
|
89
|
-
function createErrorHandler(context, _fallbackMessage = "Operation failed") {
|
|
90
|
-
return function(error) {
|
|
91
|
-
const errorMessage = normalizeError(error);
|
|
92
|
-
const fullMessage = `${context}: ${errorMessage}`;
|
|
93
|
-
console.error(fullMessage);
|
|
94
|
-
throw new Error(fullMessage);
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
async function withRetry(operation, maxRetries = 3, delay = 1e3) {
|
|
98
|
-
let lastError;
|
|
99
|
-
for (let i = 0; i <= maxRetries; i++) {
|
|
100
|
-
try {
|
|
101
|
-
return await operation();
|
|
102
|
-
} catch (error) {
|
|
103
|
-
lastError = error;
|
|
104
|
-
if (i === maxRetries) {
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
console.warn(`Operation failed, retrying in ${delay}ms... (${i + 1}/${maxRetries})`);
|
|
108
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
throw new Error(`Operation failed after ${maxRetries} retries: ${normalizeError(lastError)}`);
|
|
112
|
-
}
|
|
113
|
-
function isNonNull(value) {
|
|
114
|
-
return value !== null && value !== void 0;
|
|
115
|
-
}
|
|
116
|
-
function isValidNumber(value) {
|
|
117
|
-
return typeof value === "number" && !Number.isNaN(value) && Number.isFinite(value);
|
|
118
|
-
}
|
|
119
|
-
function isValidArrayBuffer(value) {
|
|
120
|
-
return value instanceof ArrayBuffer && value.byteLength > 0;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export { PerformanceTimer as P, isValidNumber as a, isValidArrayBuffer as b, createErrorHandler as c, isNonNull as i, measurePerformance as m, normalizeError as n, withRetry as w };
|