Skip to content

[P0][bug] 剪辑套件大面积失效:IPC 序列化总根因(已修)+ 时间轴播放/预览逻辑需按上游 1:1 重写 #142

Description

@appergb

概述

用户实测「整个剪辑套件都坏了」。逐项根因排查后,问题分两类:(A) 一个 IPC 序列化总根因(已在 #141 修复) + (B) 时间轴播放/预览逻辑需按上游 palmier-pro 1:1 重写(本 issue 收口,串联既有重写 issue)。


A. 总根因:EditRequest 多词字段 camelCase 反序列化失败(已修复,留档)

现象:删除片段、在播放头分割、Inspector 改属性、关键帧、Link/Unlink、SwapMedia、文件夹操作——点了完全没反应。删除时 toast 暴露真因:

invalid args 'command' for command 'edit_apply': missing field 'clip_ids'

根因:src-tauri/src/commands.rsEditRequest#[serde(tag="type", rename_all="camelCase")],但 serde 的 enum 级 rename_all 只改变体名、不改 struct 变体的字段名(已实测确认)。于是所有多词字段(clip_ids/clip_id/at_frame/track_index/offset_frames…)仍只认 snake_case,而前端发 camelCase → 整条命令反序列化失败、被 void 静默吞掉。只有单词字段命令(AddClips/MoveClips/TrimClips)能用——这就是"拖入/移动/修剪正常,但删除/分割/Inspector 全失效"的原因。此 bug 在 main 上同样存在,长期被误诊为'选中没生效'。

修复(#141 2975dca):给 EditRequest 每个 struct 变体加 #[serde(rename_all="camelCase")] + 回归测试。


B. 时间轴播放/预览逻辑需按上游重写(本 issue 主体)

当前预览是双渲染面拼接(播放=DOM <video>/<audio> + 自写 rAF 时钟;暂停=GPU 合成帧 <img>),与上游 Preview/VideoEngine.swift 的**单一 AVPlayer+单一 AVPlayerLayer**模型本质不同,导致一系列顽疾:

  1. 时间轴播放暂停时抽搐(单素材预览正常,但时间轴剪辑预览暂停会抽搐)。根因:暂停后残留 rAF tick 用已超前的音频 master 时间覆写播放头(集成:Codex 多功能分支 + 本轮编辑阻断修复(删除/拖入落点/蓝选/预览/菜单/递归导入) #141 加了 if(!isPlaying)return 守卫止血,但暂停逻辑需要完全重写)。
  2. 拖动时间轴预览不及时——只有松手才出正确帧,拖动中不更新。根因:合成帧靠 140ms 防抖(逐帧合成会卡死整机,见 [CRITICAL][perf] 拖动/暂停 scrub 触发逐帧 ffmpeg+wgpu 合成,可致整机卡死 #92)。应参照单素材视频预览(它本身没问题)做到实时,需流式 scrub 引擎。
  3. 整个时间轴播放逻辑都需对齐上游(play/pause/seek/scrub 都应是"同一渲染面上的状态切换",显示帧恒等于播放位置)。

需重写/标记的文件

  • web/src/components/preview/TimelinePlaybackLayer.tsx(双面 rAF 时钟 + 音频 master)
  • web/src/components/preview/Preview.tsx(<img>/<video> 切换 + 合成帧防抖)
  • web/src/components/preview/useTimelineFrame.ts(逐帧合成请求)
  • web/src/components/preview/playbackClock.ts
  • 上游权威参考:palmier-pro-upstream/Sources/PalmierPro/Preview/VideoEngine.swift(play/pause/seek/addPeriodicTimeObserver/playbackStartFrame)、PreviewView.swift(单 AVPlayerLayer + CALayer 文字叠层)。

忠实复刻路线(等价物)

WebView 跑不了 AVFoundation,单面等价物 = 流式播放引擎 #53:Rust 连续解码+合成 → MJPEG 回环(#64)+ cpal 音频(#63)→ 前端<canvas>,让 play/pause/seek/scrub 变成单面状态切换,和上游一致。

关联已有 issue


给贡献者的统一要求

所有剪辑功能一律按复刻目标仓库 palmier-pro 1:1 复刻其交互与实现,不要自己发明。涉及播放/预览的 PR 请先读上游 VideoEngine.swift 对齐语义,再在单面(#53 路线)上实现。

cc @cuic19053-hue @H-Chris233

Metadata

Metadata

Assignees

Labels

P0阻塞性 Bug,必须优先修复area:frontendReact 前端bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions