test(wave136): 多轨混音纯逻辑抽离 + 71单测 #1050

Closed
xiaoxia wants to merge 1 commits from test/wave136-multi-track-mixer-pure into develop
Owner

变更内容

新增纯逻辑模块 multi_track_mixer_pure.py

multi_track_mixer.py 中抽离所有纯函数,0 FFmpeg 依赖:

分类 函数 说明
时间计算 calculate_effective_range / is_track_visible 轨道有效时间范围计算
滤镜链 build_track_filter_chain 单轨预处理滤镜链构建
amix混音 build_amix_filter / build_mix_filter_complex / calculate_amix_volume_compensation 混音滤镜 + 音量补偿
音量计算 normalize_volume / db_to_linear / linear_to_db 音量规范化 + dB转换
排序统计 sort_tracks_by_priority / filter_enabled_tracks / count_track_types 轨道集合操作
配置验证 validate_audio_track / validate_mix_config 配置合法性校验
工具 calculate_total_tracks / estimate_mix_duration 统计与估算

71个单元测试

测试类 数量
TestCalculateEffectiveRange 9
TestIsTrackVisible 3
TestBuildTrackFilterChain 8
TestBuildAmixFilter 5
TestCalculateAmixVolumeCompensation 4
TestBuildMixFilterComplex 3
TestNormalizeVolume 6
TestDbConversion 5
TestSortTracksByPriority 4
TestFilterEnabledTracks 4
TestCountTrackTypes 3
TestValidateAudioTrack 7
TestValidateMixConfig 4
TestCalculateTotalTracks 3
TestEstimateMixDuration 3

向后兼容

  • multi_track_mixer.py 未修改,不影响现有功能
  • 后续可逐步迁移到使用 pure 模块

纯函数,无外部依赖,本地71测全绿。

## 变更内容 ### 新增纯逻辑模块 `multi_track_mixer_pure.py` 从 `multi_track_mixer.py` 中抽离所有纯函数,0 FFmpeg 依赖: | 分类 | 函数 | 说明 | |------|------|------| | 时间计算 | `calculate_effective_range` / `is_track_visible` | 轨道有效时间范围计算 | | 滤镜链 | `build_track_filter_chain` | 单轨预处理滤镜链构建 | | amix混音 | `build_amix_filter` / `build_mix_filter_complex` / `calculate_amix_volume_compensation` | 混音滤镜 + 音量补偿 | | 音量计算 | `normalize_volume` / `db_to_linear` / `linear_to_db` | 音量规范化 + dB转换 | | 排序统计 | `sort_tracks_by_priority` / `filter_enabled_tracks` / `count_track_types` | 轨道集合操作 | | 配置验证 | `validate_audio_track` / `validate_mix_config` | 配置合法性校验 | | 工具 | `calculate_total_tracks` / `estimate_mix_duration` | 统计与估算 | ### 71个单元测试 | 测试类 | 数量 | |--------|------| | TestCalculateEffectiveRange | 9 | | TestIsTrackVisible | 3 | | TestBuildTrackFilterChain | 8 | | TestBuildAmixFilter | 5 | | TestCalculateAmixVolumeCompensation | 4 | | TestBuildMixFilterComplex | 3 | | TestNormalizeVolume | 6 | | TestDbConversion | 5 | | TestSortTracksByPriority | 4 | | TestFilterEnabledTracks | 4 | | TestCountTrackTypes | 3 | | TestValidateAudioTrack | 7 | | TestValidateMixConfig | 4 | | TestCalculateTotalTracks | 3 | | TestEstimateMixDuration | 3 | ### 向后兼容 - 原 `multi_track_mixer.py` 未修改,不影响现有功能 - 后续可逐步迁移到使用 pure 模块 --- 纯函数,无外部依赖,本地71测全绿。
xiaoxia added 1 commit 2026-07-28 09:29:10 +08:00
test(wave136): 多轨混音纯逻辑抽离 + 71单测
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m28s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 19m25s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 17s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m32s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m14s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m27s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 3m23s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m21s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m10s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 2m10s
AI Code Review / AI Code Review (pull_request) Failing after 6m6s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 7m51s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 3m53s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 6m6s
CI/CD Pipeline / Deploy Production (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 / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Successful in 30s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 41s
3bdf14b5e7
- 新增 multi_track_mixer_pure.py:时间计算/滤镜链构建/amix混音/音量计算/轨道排序/配置验证
- 71个单测覆盖:effective_range/filter_chain/amix/volume_compensation/normalize_volume/dB转换/排序过滤/配置验证
- 0 FFmpeg依赖,纯函数可测试

🚀 预览环境已部署

项目 详情
PR号 #1050
预览链接 https://pr-1050.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1050 | | 预览链接 | [https://pr-1050.preview.xiaoxiajianji.com](https://pr-1050.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia closed this pull request 2026-07-28 09:53:32 +08:00

🗑️ 预览环境已清理

PR #1050 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1050 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
xiaoxia reopened this pull request 2026-07-28 12:18:39 +08:00
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:是
  • 阻塞级问题数量:3 个

📊 审查概览

  • 整体评价:需修改
  • 建议级问题数量:2 个

🔴 阻塞级问题(必须修复)

  1. [apps/worker/video_processing/multi_track_mixer_pure.py: 379] validate_mix_config 函数空指针风险

    • 问题类型:逻辑bug
    • 问题描述:当 config 字典中 tracks 键存在但值为 None 时(例如 JSON 反序列化后的 {"tracks": null}),config.get("tracks", []) 会返回 None 而不是默认值 []。随后的 for i, track in enumerate(tracks) 循环会抛出 TypeError: 'NoneType' object is not iterable,导致程序崩溃。
    • 修改建议:将 tracks = config.get("tracks", []) 修改为 tracks = config.get("tracks") or [],确保显式处理 None 值。
  2. [apps/worker/video_processing/multi_track_mixer_pure.py: 429] calculate_total_tracks 函数空指针风险

    • 问题类型:逻辑bug
    • 问题描述:同上,当 config['tracks']None 时,len(tracks) 会抛出 TypeError
    • 修改建议:将 tracks = config.get("tracks", []) 修改为 tracks = config.get("tracks") or []
  3. [apps/worker/video_processing/multi_track_mixer_pure.py: 444] estimate_mix_duration 函数空指针风险

    • 问题类型:逻辑bug
    • 问题描述:当传入的 tracks 参数为 None 时,直接进行 for t in tracks 循环会导致程序崩溃。
    • 修改建议:在函数开头增加防御性检查,如 if not tracks: return 0.0,或者将参数默认值设为 None 并在内部处理为空列表。

💡 改进建议(不阻塞合并)

  1. [apps/worker/video_processing/multi_track_mixer_pure.py: 164, 175] 模块导入位置优化

    • 具体内容:db_to_linearlinear_to_db 函数内部使用了 import math。虽然这在语法上是允许的,但作为基础工具函数,频繁调用时重复导入会有微小的性能开销。建议将 import math 移至文件顶部。
  2. [apps/worker/video_processing/multi_track_mixer_pure.py: 353] filter_enabled_tracks 判断逻辑可优化

    • 具体内容:当前判断 enabled != "false" 是大小写敏感的。如果配置来源不规范(如 "False"),可能会被误判为启用。建议统一转换为小写再判断:if bool(enabled) and str(enabled).lower() != "false" and enabled != 0:

良好实践

  • 代码结构清晰,函数职责单一,符合纯函数设计理念,易于测试。
  • 单元测试覆盖率高,包含了正常场景和多种边界条件(如负时间、零时长等),质量较高。
  • calculate_effective_range 对时间轴的截断和偏移计算逻辑严密,考虑了轨道在目标时长外、负开始时间等复杂情况。

格式检查通过 | 逻辑审查需修改 | 性能良好


🤖 由 AI 代码审查机器人自动生成 | 2026-07-28 04:39:25 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:3 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:2 个 ### 🔴 阻塞级问题(必须修复) 1. **[apps/worker/video_processing/multi_track_mixer_pure.py: 379] validate_mix_config 函数空指针风险** - 问题类型:逻辑bug - 问题描述:当 `config` 字典中 `tracks` 键存在但值为 `None` 时(例如 JSON 反序列化后的 `{"tracks": null}`),`config.get("tracks", [])` 会返回 `None` 而不是默认值 `[]`。随后的 `for i, track in enumerate(tracks)` 循环会抛出 `TypeError: 'NoneType' object is not iterable`,导致程序崩溃。 - 修改建议:将 `tracks = config.get("tracks", [])` 修改为 `tracks = config.get("tracks") or []`,确保显式处理 `None` 值。 2. **[apps/worker/video_processing/multi_track_mixer_pure.py: 429] calculate_total_tracks 函数空指针风险** - 问题类型:逻辑bug - 问题描述:同上,当 `config['tracks']` 为 `None` 时,`len(tracks)` 会抛出 `TypeError`。 - 修改建议:将 `tracks = config.get("tracks", [])` 修改为 `tracks = config.get("tracks") or []`。 3. **[apps/worker/video_processing/multi_track_mixer_pure.py: 444] estimate_mix_duration 函数空指针风险** - 问题类型:逻辑bug - 问题描述:当传入的 `tracks` 参数为 `None` 时,直接进行 `for t in tracks` 循环会导致程序崩溃。 - 修改建议:在函数开头增加防御性检查,如 `if not tracks: return 0.0`,或者将参数默认值设为 `None` 并在内部处理为空列表。 ### 💡 改进建议(不阻塞合并) 1. **[apps/worker/video_processing/multi_track_mixer_pure.py: 164, 175] 模块导入位置优化** - 具体内容:`db_to_linear` 和 `linear_to_db` 函数内部使用了 `import math`。虽然这在语法上是允许的,但作为基础工具函数,频繁调用时重复导入会有微小的性能开销。建议将 `import math` 移至文件顶部。 2. **[apps/worker/video_processing/multi_track_mixer_pure.py: 353] filter_enabled_tracks 判断逻辑可优化** - 具体内容:当前判断 `enabled != "false"` 是大小写敏感的。如果配置来源不规范(如 `"False"`),可能会被误判为启用。建议统一转换为小写再判断:`if bool(enabled) and str(enabled).lower() != "false" and enabled != 0:`。 ### ✅ 良好实践 - 代码结构清晰,函数职责单一,符合纯函数设计理念,易于测试。 - 单元测试覆盖率高,包含了正常场景和多种边界条件(如负时间、零时长等),质量较高。 - `calculate_effective_range` 对时间轴的截断和偏移计算逻辑严密,考虑了轨道在目标时长外、负开始时间等复杂情况。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ✅ 性能良好 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-28 04:39:25 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia closed this pull request 2026-07-28 13:07:43 +08:00

🗑️ 预览环境已清理

PR #1050 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1050 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Some checks are pending
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m28s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 19m25s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 17s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m32s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m14s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m27s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 3m23s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m21s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m10s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 2m10s
AI Code Review / AI Code Review (pull_request) Failing after 6m6s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 7m51s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 3m53s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 6m6s
CI/CD Pipeline / Deploy Production (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 / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Successful in 30s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 41s

Pull request closed

Sign in to join this conversation.