's'
This commit is contained in:
@@ -11,6 +11,7 @@ stats_interval_sec = 10
|
||||
|
||||
# ===== 其次:音频版权处理 =====
|
||||
# 是否启用 Demucs 人声分离(防 YouTube Content ID 版权识别)
|
||||
# 若推流几十秒后断流(YouTube 显示 no data),可设为 否 使用原始音频
|
||||
# 是 = 启用,只保留人声;否 = 使用原始音频
|
||||
enable_demucs = 是
|
||||
|
||||
|
||||
@@ -69,8 +69,8 @@ def _load_demucs_model(use_gpu: bool):
|
||||
# Demucs 模型采样率
|
||||
DEMUCS_SAMPLE_RATE = 44100
|
||||
DEMUCS_CHANNELS = 2
|
||||
# 每次处理的音频长度(秒),影响延迟与质量
|
||||
DEMUCS_CHUNK_SEC = 2.0
|
||||
# 每次处理的音频长度(秒),1.0 更易实时,2.0 质量更好但 P40 可能跟不上
|
||||
DEMUCS_CHUNK_SEC = 1.0
|
||||
# 字节 per sample (s16le: 2 bytes)
|
||||
BYTES_PER_SAMPLE = 2
|
||||
|
||||
@@ -92,7 +92,7 @@ def _demucs_separate_vocals(model, audio_chunk, device, vocal_mix_ratio=1.0, mix
|
||||
if wav.dim() == 2:
|
||||
wav = wav.unsqueeze(0)
|
||||
with torch.no_grad():
|
||||
out = apply_model(model, wav, device=device, progress=False, overlap=0.25)
|
||||
out = apply_model(model, wav, device=device, progress=False, overlap=0.1)
|
||||
# out: (batch, sources, channels, samples)
|
||||
# sources: [drums=0, bass=1, other=2, vocals=3]
|
||||
vocals = out[0, 3]
|
||||
@@ -269,19 +269,27 @@ def run_demucs_pipeline(
|
||||
"-b:v", f"{nvenc_params.get('video_bitrate_k', 4500)}k",
|
||||
"-maxrate", f"{nvenc_params.get('video_bitrate_k', 4500)+500}k",
|
||||
"-bufsize", f"{nvenc_params.get('video_bitrate_k', 4500)*2}k",
|
||||
"-vsync", "cfr", "-g", "60", "-keyint_min", "60", "-r", "30",
|
||||
"-bf", "0", "-sc_threshold", "0",
|
||||
"-x264-params", "force-cfr=1:scenecut=0:open_gop=0:sync-lookahead=0",
|
||||
"-fps_mode", "cfr", "-g", "60", "-keyint_min", "60", "-r", "30",
|
||||
"-bf", "0",
|
||||
"-pix_fmt", "yuv420p",
|
||||
"-c:a", "aac", "-b:a", "128k", "-ar", "48000", "-ac", "2",
|
||||
"-af", "lowpass=f=9000,aresample=async=1:first_pts=0",
|
||||
"-flags", "+global_header", "-flvflags", "no_duration_filesize",
|
||||
"-f", "flv", youtube_rtmp,
|
||||
]
|
||||
if nvenc_params.get("tune_param"):
|
||||
# NVENC 用 tune_param;libx264 用 sc_threshold + x264-params
|
||||
codec = nvenc_params.get("codec_v", "libx264")
|
||||
if nvenc_params.get("tune_param") and codec == "h264_nvenc":
|
||||
idx = ffmpeg_out_cmd.index("-profile:v")
|
||||
for p in reversed(nvenc_params["tune_param"]):
|
||||
ffmpeg_out_cmd.insert(idx, p)
|
||||
elif codec == "libx264":
|
||||
idx = ffmpeg_out_cmd.index("-bf")
|
||||
ffmpeg_out_cmd.insert(idx + 2, "-sc_threshold")
|
||||
ffmpeg_out_cmd.insert(idx + 3, "0")
|
||||
idx = ffmpeg_out_cmd.index("-pix_fmt")
|
||||
ffmpeg_out_cmd.insert(idx, "-x264-params")
|
||||
ffmpeg_out_cmd.insert(idx + 1, "force-cfr=1:scenecut=0:open_gop=0:sync-lookahead=0")
|
||||
|
||||
proc_v = None
|
||||
proc_a = None
|
||||
@@ -385,7 +393,8 @@ def run_demucs_pipeline(
|
||||
except queue.Empty:
|
||||
# 若 proc_out(推流进程)已异常退出,立即报告
|
||||
if proc_out.poll() is not None and proc_out.returncode != 0:
|
||||
print(f"[ERROR] YouTube 推流进程已退出,返回码: {proc_out.returncode}")
|
||||
print(f"[ERROR] YouTube 推流进程已退出,返回码: {proc_out.returncode},可能是 Demucs 处理跟不上或网络问题")
|
||||
print(f"[TIP] 若频繁断流,可尝试 config/youtube.ini 中设置 enable_demucs = 否 使用原始音频")
|
||||
break
|
||||
if time.time() - getattr(proc_v, "last_out_ts", time.time()) > stale_output_seconds:
|
||||
print("[WARN] 长时间无任何日志,强制重启进程")
|
||||
|
||||
@@ -258,7 +258,7 @@ def start_douyin_youtube_ffplay(
|
||||
"-profile:v", "high",
|
||||
# 720p,画质优先,YouTube 推荐 3-8 Mbps
|
||||
"-b:v", f"{br_k}k", "-maxrate", f"{br_k+500}k", "-bufsize", f"{br_k*2}k",
|
||||
"-vsync", "cfr",
|
||||
"-fps_mode", "cfr",
|
||||
"-g", "60", "-keyint_min", "60",
|
||||
"-r", "30",
|
||||
"-bf", "0",
|
||||
|
||||
Reference in New Issue
Block a user