feat: 绿幕抠像 + 音频降噪引擎(Chroma Key + Noise Reduction) (#303)
CI/CD Pipeline / Validate Code Quality And Tests (push) Successful in 39s
CI/CD Pipeline / Unit Tests (push) Successful in 1m22s
CI/CD Pipeline / Frontend Lint (push) Successful in 1m22s
CI/CD Pipeline / Build Production Runtime Images (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Failing after 1m13s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Validate Code Quality And Tests (push) Successful in 39s
CI/CD Pipeline / Unit Tests (push) Successful in 1m22s
CI/CD Pipeline / Frontend Lint (push) Successful in 1m22s
CI/CD Pipeline / Build Production Runtime Images (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Failing after 1m13s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
This commit was merged in pull request #303.
This commit is contained in:
@@ -35,6 +35,8 @@ class RenderContext:
|
||||
|
||||
work_dir: Path
|
||||
plan_id: str
|
||||
# 音频降噪配置(全局,对最终混音结果应用)
|
||||
noise_reduction_config: dict | None = None
|
||||
# 音频探测缓存(避免同一 clip 被多次 ffprobe)
|
||||
_audio_cache: dict[str, bool] = field(default_factory=dict)
|
||||
|
||||
@@ -153,12 +155,58 @@ def mix_audio(
|
||||
try:
|
||||
# 这里 main_audio 就是 output_path,先有主音频再混 BGM
|
||||
final_path = mix_bgm_with_main(ctx, output_path, bgm_cfg, video_duration)
|
||||
return final_path
|
||||
return _apply_noise_reduction_if_needed(ctx, final_path)
|
||||
except Exception:
|
||||
logger.exception("[bgm] BGM 混音失败,回退到无 BGM 音频: plan_id=%s", ctx.plan_id)
|
||||
return output_path
|
||||
return _apply_noise_reduction_if_needed(ctx, output_path)
|
||||
|
||||
return output_path
|
||||
return _apply_noise_reduction_if_needed(ctx, output_path)
|
||||
|
||||
|
||||
def _apply_noise_reduction_if_needed(ctx: RenderContext, audio_path: Path) -> Path:
|
||||
"""如果配置了音频降噪,对已生成的音频文件应用降噪。
|
||||
|
||||
作为后处理步骤,对最终混音结果统一降噪。
|
||||
失败时返回原始文件路径,不阻断主流程。
|
||||
"""
|
||||
if not ctx.noise_reduction_config:
|
||||
return audio_path
|
||||
|
||||
try:
|
||||
from video_processing.noise_reduction_engine import NoiseReductionConfig, NoiseReductionEngine
|
||||
|
||||
config = NoiseReductionConfig.from_dict(ctx.noise_reduction_config)
|
||||
if not config.has_effect():
|
||||
return audio_path
|
||||
|
||||
engine = NoiseReductionEngine(config)
|
||||
filter_str = engine.build_filter("[0:a]", "[out]")
|
||||
# 提取滤镜部分(不带标签)
|
||||
filter_part = filter_str[len("[0:a]") : -len("[out]")]
|
||||
|
||||
nr_output_path = audio_path.with_name(f"{audio_path.stem}_nr.aac")
|
||||
command = [
|
||||
FFMPEG_BIN,
|
||||
"-y",
|
||||
"-i",
|
||||
str(audio_path),
|
||||
"-af",
|
||||
filter_part,
|
||||
"-acodec",
|
||||
"aac",
|
||||
"-b:a",
|
||||
"128k",
|
||||
str(nr_output_path),
|
||||
]
|
||||
run_ffmpeg(command)
|
||||
|
||||
if nr_output_path.exists():
|
||||
return nr_output_path
|
||||
logger.warning("[noise-reduction] 降噪输出文件不存在,使用原始音频")
|
||||
return audio_path
|
||||
except Exception as e:
|
||||
logger.warning("[noise-reduction] 音频降噪失败,使用原始音频: %s", e)
|
||||
return audio_path
|
||||
|
||||
|
||||
def concat_main_audio(
|
||||
|
||||
Reference in New Issue
Block a user