Files
ViGent2/Docs/DevLogs/Day24.md
Kevin Wong 035ee29d72 更新
2026-02-11 14:33:05 +08:00

8.3 KiB
Raw Blame History

🔧 鉴权到期治理 + 多素材时间轴稳定性修复 (Day 24)

概述

本日主要完成两条主线:

  1. 账号与鉴权治理:会员到期改为请求时自动失效(登录/鉴权接口触发),并统一返回续费提示。
  2. 视频生成稳定性:围绕多素材时间轴、截取语义、拼接边界冻结、画面比例与字幕标题适配进行一轮端到端修复。

🔐 会员到期请求时失效 — 第一阶段 (Day 24)

目标

避免依赖定时任务,用户在触发登录或访问受保护接口时即可完成到期判定与账号停用。

行为调整

  • 到期判断基于 users.expires_at
  • 判定到期后:
    • is_active 自动置为 false
    • 删除该用户全部 session
    • 返回 403,提示:会员已到期,请续费

实现点

  • users.py 新增 deactivate_user_if_expired(),并补充 _parse_expires_at() 统一时区解析。
  • deps.pyget_current_user / get_current_user_optional 中统一接入到期检查。
  • auth/router.py 在登录路径增加到期停用逻辑;/api/auth/me 统一走 Depends(get_current_user)

🖼️ 画面比例控制 + 字幕标题适配 — 第二阶段 (Day 24)

2.1 输出画面比例可配置

  • 时间轴顶部新增“画面比例”下拉:9:16 / 16:9
  • 默认值 9:16,并持久化到 localStorage。
  • 生成请求携带 output_aspect_ratio,后端在单素材与多素材流程中统一按目标分辨率处理。

2.2 标题/字幕在窄屏画布防溢出

为减少“预览正常、成片溢出”的差异,统一了预览与渲染策略:

  • 根据 composition 宽度进行响应式缩放。
  • 开启可换行:white-space: normal + word-break + overflow-wrap
  • 描边、字距、上下边距同步按比例缩放。

2.3 片头标题显示模式(短暂/常驻)

  • 在“标题与字幕”面板的“片头标题”行尾新增下拉,支持:短暂显示 / 常驻显示
  • 默认模式为 短暂显示,短暂模式默认时长为 4 秒。
  • 用户选择会持久化到 localStorage刷新后保持上次配置。
  • 生成请求新增 title_display_mode,短暂模式透传 title_duration=4.0
  • Remotion 端到端支持该参数:
    • short:标题在设定时长后淡出并结束渲染;
    • persistent:标题全程常驻(保留淡入动画,不执行淡出)。

🎥 方向归一化 + 多素材拼接稳定性 — 第三阶段 (Day 24)

3.1 MOV 旋转元数据导致横竖识别错误

问题场景:编码分辨率是横屏,但依赖 rotation side-data 才能正确显示为竖屏(常见于手机 MOV

修复方案:

  • get_video_metadata() 扩展返回 rotation/effective_width/effective_height
  • 新增 normalize_orientation(),在流程前对带旋转元数据素材做物理方向归一化。
  • 单素材和多素材下载后统一执行方向归一化,再做分辨率决策。

3.2 多素材“只看到第一段”与边界冻结

针对拼接可靠性补了两类保护:

  • 分配保护custom_assignments 与素材数量不一致时,后端回退自动分配,避免异常输入导致仅首段生效。
  • 编码一致性
    • 片段准备阶段统一重编码;
    • concat 阶段不再走拷贝;
    • 进一步统一为 25fps + CFR,并在 concat 增加 +genpts,降低段边界时间基不连续导致的“画面冻结口型还动”风险。

⏱️ 时间轴截取语义对齐修复 — 第四阶段 (Day 24)

背景

时间轴设计语义是:

  • 每段可以设置 sourceStart/sourceEnd
  • 总时长超出音频时,仅保留可见段,末段截齐音频;
  • 总时长不足时,由最后可见段循环补齐。

本日将前后端对齐到这一语义。

4.1 source_end 全链路打通

此前仅传 source_start,导致后端无法准确知道“截到哪里”。

本次改动:

  • 前端 toCustomAssignments() 增加可选 source_end
  • 后端 CustomAssignment schema 增加 source_end
  • workflow 将 source_end 透传到 prepare_segment()(单素材/多素材均支持)。
  • prepare_segment() 增加 source_end 参数,按 [source_start, source_end) 计算可用片段,并在需要循环时先裁剪再循环,避免循环范围错位。

4.2 时间轴有效时长计算修复

修复 sourceStart > 0 且 sourceEnd = 0 时的有效时长错误:

  • 旧逻辑会按整段素材时长计算;
  • 新逻辑改为 materialDuration - sourceStart

该修复同时用于:

  • recalcPositions() 的段时长计算;
  • TimelineEditor 中“循环补足”可视化比例计算。

4.3 可见段分配优先级修复

修复“可见段数 < 已选素材数时custom_assignments 被丢弃回退自动分配”的问题:

  • 生成请求优先以时间轴可见段的 assignments 为准;
  • 超出时间轴的素材不参与本次生成。

4.4 单素材截取触发条件补齐

单素材模式下,若只改了终点(sourceEnd > 0)也会发送 custom_assignments,确保截取生效。


🧭 页面交互与体验细节 — 第五阶段 (Day 24)

  • 页面刷新后自动回到顶部,避免从历史滚动位置进入页面。
  • 素材列表与历史视频列表滚动增加“跳过首次自动滚动”保护,减少恢复状态时页面跳动。
  • 时间轴比例区移除多余文案,保持信息简洁。

涉及文件汇总

后端修改

文件 变更
backend/app/repositories/users.py 新增 deactivate_user_if_expired()_parse_expires_at()
backend/app/core/deps.py get_current_user / get_current_user_optional 接入到期失效检查
backend/app/modules/auth/router.py 登录时到期停用 + /api/auth/me 统一鉴权依赖
backend/app/modules/videos/schemas.py CustomAssignment 新增 source_end;保留 output_aspect_ratio
backend/app/modules/videos/workflow.py 多素材/单素材透传 source_end;多素材 prepare/concat 统一 25fps标题显示模式参数透传 Remotion
backend/app/services/video_service.py 旋转元数据解析与方向归一化;prepare_segment 支持 source_end/target_fpsconcat 强制 CFR + +genpts
backend/app/services/remotion_service.py render 支持 title_display_mode/title_duration 并传递到 render.ts

前端修改

文件 变更
frontend/src/features/home/model/useTimelineEditor.ts CustomAssignment 新增 source_end;修复 sourceStart 开放终点时长计算
frontend/src/features/home/model/useHomeController.ts 多素材以可见 assignments 为准发送;单素材截取触发条件补齐
frontend/src/features/home/ui/TimelineEditor.tsx 画面比例下拉;循环比例按截取后有效时长计算
frontend/src/features/home/model/useHomePersistence.ts outputAspectRatiotitleDisplayMode 持久化
frontend/src/features/home/ui/HomePage.tsx 页面进入滚动到顶部ClipTrimmer/Timeline 交互保持一致
frontend/src/features/home/ui/FloatingStylePreview.tsx 标题/字幕样式预览与成片渲染策略对齐
frontend/src/features/home/ui/TitleSubtitlePanel.tsx 标题行新增“短暂显示/常驻显示”下拉

Remotion 修改

文件 变更
remotion/src/components/Title.tsx 标题响应式缩放与自动换行;新增短暂/常驻显示模式控制
remotion/src/components/Subtitles.tsx 字幕响应式缩放与自动换行,减少预览/成片差异
remotion/src/Video.tsx 新增 titleDisplayMode 透传到标题组件
remotion/src/Root.tsx 默认 props 增加 titleDisplayMode='short'titleDuration=4
remotion/render.ts CLI 参数新增 --titleDisplayModeinputProps 增加 titleDisplayMode

验证记录

  • 后端语法检查:python -m py_compile backend/app/modules/videos/schemas.py backend/app/modules/videos/workflow.py backend/app/services/video_service.py backend/app/services/remotion_service.py
  • 前端类型检查:npx tsc --noEmit
  • 前端 ESLintnpx eslint src/features/home/model/useHomeController.ts src/features/home/model/useHomePersistence.ts src/features/home/ui/HomePage.tsx src/features/home/ui/TitleSubtitlePanel.tsx
  • Remotion 渲染脚本构建:npm run build:render