feat: 多轨道混音 + 字幕渲染引擎 + 视频拼接(后端) #312

Merged
xiaoxia merged 6 commits from feat/multi-track-mix-subtitle-concat into develop 2026-07-14 15:20:47 +08:00
Owner

三个渲染能力后端实现

1. 多轨道混音(multi_track_mixer.py)

  • 支持任意数量音频轨道(原音/BGM/配音/音效/环境音)
  • 每轨独立音量调节(0~2x)、淡入淡出、时间偏移(delay)
  • 主输出音量控制 + 智能归一化补偿
  • 5种轨道类型预设默认音量
  • 降级策略:单轨失败自动跳过,混音整体失败回退主音频

2. 字幕渲染引擎(subtitle_render_engine.py)

  • 统一 SubtitleStyle 配置:字体/颜色/描边/阴影/背景框
  • 9宫格位置 + 自定义边距
  • 多源字幕合并:标题 / 静态字幕 / ASR时间轴 / 手动字幕
  • 淡入淡出动画效果(\fad)
  • 长文本自动换行(优先标点处断开)
  • 便捷函数:build_subtitles_from_plan + build_subtitle_filter
  • 向后兼容:不影响现有 render_subtitles / subtitle_generator

3. 视频拼接引擎(concat_engine.py)

  • 两种模式智能切换:
    • concat demuxer(stream copy):参数一致时秒级完成,无质量损失
    • concat filter(重新编码):支持不同分辨率/帧率/编码的视频
  • 每段独立裁剪(start_time + duration)
  • 输出分辨率/帧率可指定,自动 scale + pad 补齐
  • 降级策略:某段视频失败自动跳过,不阻断整体拼接

接入方式

  • render_audio.pymix_audio 新增 audio_tracks_config 参数,在 BGM 混音之后应用
  • unified_render_service.py:从 plan.config.audio_tracks 读取配置,零侵入数据模型

测试

  • 52 个新增单测(多轨道 12 + 字幕 20 + 视频拼接 20)
  • 全套 2014 个单测全绿
  • 零回归
## 三个渲染能力后端实现 ### 1. 多轨道混音(multi_track_mixer.py) - 支持任意数量音频轨道(原音/BGM/配音/音效/环境音) - 每轨独立音量调节(0~2x)、淡入淡出、时间偏移(delay) - 主输出音量控制 + 智能归一化补偿 - 5种轨道类型预设默认音量 - **降级策略**:单轨失败自动跳过,混音整体失败回退主音频 ### 2. 字幕渲染引擎(subtitle_render_engine.py) - 统一 SubtitleStyle 配置:字体/颜色/描边/阴影/背景框 - 9宫格位置 + 自定义边距 - 多源字幕合并:标题 / 静态字幕 / ASR时间轴 / 手动字幕 - 淡入淡出动画效果(\fad) - 长文本自动换行(优先标点处断开) - 便捷函数:`build_subtitles_from_plan` + `build_subtitle_filter` - **向后兼容**:不影响现有 render_subtitles / subtitle_generator ### 3. 视频拼接引擎(concat_engine.py) - 两种模式智能切换: - **concat demuxer**(stream copy):参数一致时秒级完成,无质量损失 - **concat filter**(重新编码):支持不同分辨率/帧率/编码的视频 - 每段独立裁剪(start_time + duration) - 输出分辨率/帧率可指定,自动 scale + pad 补齐 - **降级策略**:某段视频失败自动跳过,不阻断整体拼接 ### 接入方式 - `render_audio.py`:`mix_audio` 新增 `audio_tracks_config` 参数,在 BGM 混音之后应用 - `unified_render_service.py`:从 `plan.config.audio_tracks` 读取配置,零侵入数据模型 ### 测试 - ✅ 52 个新增单测(多轨道 12 + 字幕 20 + 视频拼接 20) - ✅ 全套 2014 个单测全绿 - ✅ 零回归
xiaoxia added 1 commit 2026-07-14 11:36:12 +08:00
feat: 多轨道混音 + 字幕渲染引擎 + 视频拼接
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Failing after 1m17s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m21s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Successful in 1m40s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 4m23s
0bfff35301
三个渲染能力后端实现:

1. 多轨道混音(multi_track_mixer.py)
   - 支持任意数量音频轨道(原音/BGM/配音/音效/环境音)
   - 每轨独立音量、淡入淡出、时间偏移
   - 主输出音量控制 + 归一化补偿
   - 降级:单轨失败自动跳过,混音失败回退主音频

2. 字幕渲染引擎(subtitle_render_engine.py)
   - 统一 SubtitleStyle 配置:字体/颜色/描边/阴影/背景框/位置
   - 9宫格位置 + 自定义边距
   - 多源字幕合并:标题/静态字幕/ASR时间轴/手动字幕
   - 淡入淡出动画效果
   - 长文本自动换行
   - 便捷函数 build_subtitles_from_plan + build_subtitle_filter

3. 视频拼接引擎(concat_engine.py)
   - 两种模式:concat demuxer(stream copy,最快)+ concat filter(重新编码)
   - 自动选择最优模式,参数不一致时智能降级
   - 支持每段独立裁剪(start_time + duration)
   - 支持输出分辨率/帧率指定,自动缩放+pad补齐
   - 降级:某段失败跳过,不阻断整体拼接

接入:
- render_audio.py: mix_audio 新增 audio_tracks_config 参数
- unified_render_service.py: 从 plan.config.audio_tracks 读取配置

52个新增单测 + 2014个全套测试全绿,零回归
Author
Owner

安全审计报告 - PR #312 多轨道混音 + 字幕渲染引擎 + 视频拼接

结论:⚠️ 有条件通过(需修复 P1 问题后方可合并)

等级 数量
P0 🔴 0
P1 🟠 4
P2 🟡 9
P3 🟢 5
合计 18

🔴 P0(致命)

无。所有 FFmpeg 调用均通过 run_ffmpeg 使用列表参数,不存在命令注入。


🟠 P1(高危 — 必须修复)

1. multi_track_mixer.py: audio_path 无路径安全校验

  • AudioTrack.from_dictaudio_path 直接从用户配置读取,无路径校验
  • 用户可通过 plan.config.audio_tracks.tracks[].audio_path 传入任意文件路径
  • 风险:任意文件读取/探测(信息泄露)
  • 建议:使用 asset_id 解析模式,或引入 path_security 校验

2. concat_engine.py: video_path 无路径安全校验

  • ConcatSegment.from_dictvideo_path 同理,无任何路径安全校验
  • 风险:任意文件读取/探测
  • 建议:同上

3. multi_track_mixer.py: 无轨道数量上限

  • from_config_dict 不限制 tracks 数量,可传入成百上千轨道
  • 风险:资源耗尽(DoS),大量文件打开 + 复杂 filter_complex
  • 建议:MAX_TRACKS = 16,超过则截断告警

4. concat_engine.py: 无拼接段数上限

  • segments 无数量上限,concat filter 模式下内存线性增长
  • 风险:资源耗尽(DoS)
  • 建议:MAX_SEGMENTS = 50

🟡 P2(中危 — 建议修复)

# 问题 文件
1 拼接无总时长/单段时长上限 concat_engine.py
2 预处理临时轨道文件未清理 multi_track_mixer.py
3 concat_list.txt 使用后未清理 concat_engine.py
4 transition 字段无白名单校验 concat_engine.py
5 字幕滤镜路径未转义 [ ] subtitle_render_engine.py
6 字幕片段数量/文件大小无上限 subtitle_render_engine.py
7 _concat_filter 约 100 行死代码(前半部分全部 clear 掉) concat_engine.py
8 track_id/track_type 无字符校验(日志注入风险) multi_track_mixer.py
9 API 层 config_schemas 未校验新增配置字段 config_schemas.py

🟢 P3(优化建议)

# 问题
1 concat_engine.py 中 tempfiletyping.Any 导入未使用
2 subtitle_render_engine.py 中 3 个导入未使用(预留)
3 SubtitleRenderEngine 尚未集成到主渲染流程
4 ConcatEngine 尚未集成到主渲染流程
5 transition 字段注释与实际逻辑不一致

亮点

  1. 降级策略完善:单轨失败跳过、混音失败回退主音频、参数不一致自动降级,不阻断主流程
  2. 参数安全转换:所有数字参数 try/except + 范围钳制,类型安全
  3. 统一 run_ffmpeg:全部走列表参数,从根源避免 shell 注入
  4. 单测覆盖充分:52 个单测覆盖配置解析、正常流程、异常场景、降级路径
  5. ASS 文本转义到位:正确转义大括号防止覆盖标签注入

📋 修复优先级 Top 5

  1. audio_path / video_path 路径安全校验 🔴
  2. 轨道数量上限 🟠
  3. 拼接段数上限 🟠
  4. 拼接总时长上限 🟡
  5. 临时文件清理 🟡

完整报告已上传至项目 docs/ 目录

## 安全审计报告 - PR #312 多轨道混音 + 字幕渲染引擎 + 视频拼接 **结论:⚠️ 有条件通过(需修复 P1 问题后方可合并)** | 等级 | 数量 | |------|------| | P0 🔴 | 0 | | P1 🟠 | 4 | | P2 🟡 | 9 | | P3 🟢 | 5 | | **合计** | **18** | --- ### 🔴 P0(致命) 无。所有 FFmpeg 调用均通过 `run_ffmpeg` 使用列表参数,不存在命令注入。 --- ### 🟠 P1(高危 — 必须修复) **1. multi_track_mixer.py: audio_path 无路径安全校验** - `AudioTrack.from_dict` 中 `audio_path` 直接从用户配置读取,无路径校验 - 用户可通过 `plan.config.audio_tracks.tracks[].audio_path` 传入任意文件路径 - 风险:任意文件读取/探测(信息泄露) - 建议:使用 asset_id 解析模式,或引入 path_security 校验 **2. concat_engine.py: video_path 无路径安全校验** - `ConcatSegment.from_dict` 中 `video_path` 同理,无任何路径安全校验 - 风险:任意文件读取/探测 - 建议:同上 **3. multi_track_mixer.py: 无轨道数量上限** - `from_config_dict` 不限制 tracks 数量,可传入成百上千轨道 - 风险:资源耗尽(DoS),大量文件打开 + 复杂 filter_complex - 建议:`MAX_TRACKS = 16`,超过则截断告警 **4. concat_engine.py: 无拼接段数上限** - `segments` 无数量上限,concat filter 模式下内存线性增长 - 风险:资源耗尽(DoS) - 建议:`MAX_SEGMENTS = 50` --- ### 🟡 P2(中危 — 建议修复) | # | 问题 | 文件 | |---|------|------| | 1 | 拼接无总时长/单段时长上限 | concat_engine.py | | 2 | 预处理临时轨道文件未清理 | multi_track_mixer.py | | 3 | concat_list.txt 使用后未清理 | concat_engine.py | | 4 | transition 字段无白名单校验 | concat_engine.py | | 5 | 字幕滤镜路径未转义 `[` `]` | subtitle_render_engine.py | | 6 | 字幕片段数量/文件大小无上限 | subtitle_render_engine.py | | 7 | `_concat_filter` 约 100 行死代码(前半部分全部 clear 掉) | concat_engine.py | | 8 | track_id/track_type 无字符校验(日志注入风险) | multi_track_mixer.py | | 9 | API 层 config_schemas 未校验新增配置字段 | config_schemas.py | --- ### 🟢 P3(优化建议) | # | 问题 | |---|------| | 1 | concat_engine.py 中 `tempfile`、`typing.Any` 导入未使用 | | 2 | subtitle_render_engine.py 中 3 个导入未使用(预留) | | 3 | SubtitleRenderEngine 尚未集成到主渲染流程 | | 4 | ConcatEngine 尚未集成到主渲染流程 | | 5 | transition 字段注释与实际逻辑不一致 | --- ### ✨ 亮点 1. **降级策略完善**:单轨失败跳过、混音失败回退主音频、参数不一致自动降级,不阻断主流程 2. **参数安全转换**:所有数字参数 try/except + 范围钳制,类型安全 3. **统一 run_ffmpeg**:全部走列表参数,从根源避免 shell 注入 4. **单测覆盖充分**:52 个单测覆盖配置解析、正常流程、异常场景、降级路径 5. **ASS 文本转义到位**:正确转义大括号防止覆盖标签注入 --- ### 📋 修复优先级 Top 5 1. audio_path / video_path 路径安全校验 🔴 2. 轨道数量上限 🟠 3. 拼接段数上限 🟠 4. 拼接总时长上限 🟡 5. 临时文件清理 🟡 --- *完整报告已上传至项目 docs/ 目录*
xiaoxia added 1 commit 2026-07-14 15:12:31 +08:00
xiaoxia added 1 commit 2026-07-14 15:12:31 +08:00
style: black + isort format
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Has been cancelled
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
9961d0d3d9
xiaoxia added 1 commit 2026-07-14 15:12:32 +08:00
style: black + isort format
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Has been cancelled
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
50b6d59ab8
xiaoxia added 1 commit 2026-07-14 15:12:34 +08:00
style: black + isort format
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Has been cancelled
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
0f3881443f
xiaoxia added 1 commit 2026-07-14 15:12:39 +08:00
style: black + isort format
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 47s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 1m48s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m26s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m12s
4b13efb488
xiaoxia merged commit f268e208de into develop 2026-07-14 15:20:47 +08:00
Sign in to join this conversation.