按《DSH 开发文档 v1.6》4.11(T-WEB-014,用户标注「重要」): 服务端: - 抽出公共 PNG 编码器 src/common/png.ts(模型缩略图改为复用,零原生依赖不变) - 新增 src/motions/motion-thumbnail.ts:关键点序列 -> 正视图骨架 PNG (复用 33 点 PARENT_TABLE 连线,包围盒按整段计算,低置信度点不画) - motions 增 thumbnail_asset_id(迁移 AddMotionThumbnail)+ AssetKind.MotionThumbnail - /preprocess 生成缩略图并落库,失败只记 warning;MotionDto 增 thumbnailUrl(契约 0.6.0) 管理端: - 新增 MotionPreview:懒加载 NDJSON -> 骨架线框 + 关节实例球体 支持播放/暂停、上一帧/下一帧、时间轴拖动、0.25x-2x 变速、循环 叠加帧号/当前时间/总时长,按整段包围盒自动取景 three.js 单独分包(lazy + Suspense),主包 241 kB 不涨 - 动作列表新增 40px 骨架缩略图列(点击开预览)+ 预览按钮 + 内联预览面板 - 新增 admin/src/lib/keypoint-sequence.ts 与 lib/skeleton-topology.ts 测试:新增 8 项;规模 18 文件 / 237 项。版本 0.5.0。
66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
import { MotionFormat, PreprocessState, PublishStatus, SourceType } from '../common/enums';
|
|
import { Motion } from '../entities/motion.entity';
|
|
|
|
/** 契约 data-models.md §3 的对外表示 */
|
|
export interface MotionDto {
|
|
id: number;
|
|
songId: number | null;
|
|
name: string;
|
|
format: MotionFormat;
|
|
fileUrl: string | null;
|
|
fileSize: number | null;
|
|
fps: number | null;
|
|
frameCount: number | null;
|
|
durationMs: number | null;
|
|
keypointFormat: string | null;
|
|
keypointUrl: string | null;
|
|
/** 骨架缩略图(预处理时生成;T-WEB-014) */
|
|
thumbnailUrl: string | null;
|
|
keypointFrames: number | null;
|
|
preprocessState: PreprocessState;
|
|
preprocessError: string | null;
|
|
sourceType: SourceType;
|
|
sourceName: string;
|
|
sourceUrl: string;
|
|
license: string;
|
|
author: string;
|
|
status: PublishStatus;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface MotionUrlLookup {
|
|
fileUrl: string | null;
|
|
keypointUrl: string | null;
|
|
fileSize?: number | null;
|
|
thumbnailUrl: string | null;
|
|
}
|
|
|
|
export function toMotionDto(motion: Motion, urls: MotionUrlLookup): MotionDto {
|
|
return {
|
|
id: motion.id,
|
|
songId: motion.songId,
|
|
name: motion.name,
|
|
format: motion.format,
|
|
fileUrl: urls.fileUrl,
|
|
fileSize: urls.fileSize ?? null,
|
|
fps: motion.fps,
|
|
frameCount: motion.frameCount,
|
|
durationMs: motion.durationMs,
|
|
keypointFormat: motion.keypointFormat,
|
|
keypointUrl: urls.keypointUrl,
|
|
thumbnailUrl: urls.thumbnailUrl,
|
|
keypointFrames: motion.keypointFrames,
|
|
preprocessState: motion.preprocessState,
|
|
preprocessError: motion.preprocessError,
|
|
sourceType: motion.sourceType,
|
|
sourceName: motion.sourceName,
|
|
sourceUrl: motion.sourceUrl,
|
|
license: motion.license,
|
|
author: motion.author,
|
|
status: motion.status,
|
|
createdAt: motion.createdAt.toISOString(),
|
|
updatedAt: motion.updatedAt.toISOString(),
|
|
};
|
|
}
|