815998acaa
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 27s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m9s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 49s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m3s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 1m51s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 32s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m21s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m25s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m1s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m24s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 6m4s
AI Code Review / AI Code Review (pull_request) Successful in 6m38s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m55s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 3m10s
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 22s
CI/CD Pipeline / Production Browser E2E (pull_request) Failing after 1229h45m2s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 1230h4m14s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 1230h4m16s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 1230h5m12s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 1230h4m18s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 1230h11m47s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 1230h13m49s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 1230h13m51s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 1230h13m53s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 1230h40m52s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 1230h40m54s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 1230h40m56s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 1230h46m31s
- 从 noise_reduction_engine.py 抽离领域模型到 packages/domain/noise_reduction_config.py - noise_reduction_engine.py: 229→72行 (-69%) - 新增 39 个单测,覆盖 NoiseReductionConfig 全部纯逻辑 - 原有 27 个测试无回归 - 保持向后兼容:引擎模块保留全部公开接口作为薄包装
73 lines
2.4 KiB
Python
Executable File
73 lines
2.4 KiB
Python
Executable File
"""音频降噪引擎 — 基于 FFmpeg afftdn 滤镜.
|
||
|
||
支持对音频进行背景噪音消除、人声增强,适用于语音录制、采访等场景。
|
||
|
||
领域模型已抽离至 packages/domain/noise_reduction_config.py,本模块保留薄包装以维持向后兼容。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
|
||
from packages.domain.noise_reduction_config import ( # noqa: F401 — 向后兼容
|
||
NoiseReductionLevel,
|
||
NoiseReductionConfig,
|
||
build_afftdn_filter as _build_afftdn_filter_base,
|
||
build_arnndn_filter as _build_arnndn_filter_base,
|
||
apply_noise_reduction_if_needed as _apply_noise_reduction_if_needed_base,
|
||
)
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
class NoiseReductionEngine:
|
||
"""音频降噪引擎 — 薄包装,实际逻辑在 domain.noise_reduction_config.
|
||
|
||
基于 FFmpeg afftdn(Audio FFt Denoiser)滤镜实现:
|
||
- 使用短时傅里叶变换分析音频频谱
|
||
- 识别并消除稳态背景噪音
|
||
- 保留人声等非稳态信号
|
||
"""
|
||
|
||
def __init__(self, config: NoiseReductionConfig):
|
||
self.config = config
|
||
|
||
def build_filter(self, input_label: str, output_label: str) -> str:
|
||
"""构建音频降噪滤镜字符串.
|
||
|
||
Args:
|
||
input_label: 输入标签,如 "[0:a]" 或 "[a0]"
|
||
output_label: 输出标签,如 "[nr0]"
|
||
|
||
Returns:
|
||
FFmpeg 滤镜字符串
|
||
"""
|
||
return _build_afftdn_filter_base(self.config, input_label, output_label)
|
||
|
||
def build_filter_arnndn(self, input_label: str, output_label: str, model_file: str) -> str:
|
||
"""使用 RNN 降噪滤镜(arnndn,效果更好但需要模型文件).
|
||
|
||
Args:
|
||
input_label: 输入标签
|
||
output_label: 输出标签
|
||
model_file: RNNNoise 模型文件路径
|
||
|
||
Returns:
|
||
FFmpeg 滤镜字符串
|
||
"""
|
||
return _build_arnndn_filter_base(self.config, input_label, output_label, model_file)
|
||
|
||
|
||
def apply_noise_reduction_if_needed(config_data, input_label: str, output_label: str):
|
||
"""便捷函数:根据配置判断是否需要应用音频降噪.
|
||
|
||
Args:
|
||
config_data: 降噪配置字典
|
||
input_label: 输入标签
|
||
output_label: 输出标签
|
||
|
||
Returns:
|
||
滤镜字符串,不需要降噪时返回 None
|
||
"""
|
||
return _apply_noise_reduction_if_needed_base(config_data, input_label, output_label)
|