s
This commit is contained in:
@@ -126,11 +126,11 @@ def _resolve_youtube_push_config_file(config_file: str | None = None, *, base_di
|
||||
def _load_youtube_push_settings(config_file: str) -> dict[str, str | bool]:
|
||||
settings: dict[str, str | bool] = {
|
||||
"use_rtmps": True,
|
||||
"b_v": "2800k",
|
||||
"maxrate": "3200k",
|
||||
"bufsize": "5600k",
|
||||
"b_v": "4000k",
|
||||
"maxrate": "4500k",
|
||||
"bufsize": "8000k",
|
||||
"stream_key": "",
|
||||
"fast_audio": True,
|
||||
"fast_audio": False,
|
||||
}
|
||||
if not os.path.exists(config_file):
|
||||
return settings
|
||||
@@ -144,8 +144,8 @@ def _load_youtube_push_settings(config_file: str) -> dict[str, str | bool]:
|
||||
v = (v or "").strip()
|
||||
if k == "rtmps" and v.lower() in ("0", "false", "否"):
|
||||
settings["use_rtmps"] = False
|
||||
elif k == "fast_audio" and v.lower() in ("1", "true", "yes", "是", "开", "on"):
|
||||
settings["fast_audio"] = True
|
||||
elif k == "fast_audio":
|
||||
settings["fast_audio"] = v.lower() in ("1", "true", "yes", "是", "开", "on")
|
||||
elif k == "bitrate" and v:
|
||||
try:
|
||||
n = int(v)
|
||||
@@ -182,10 +182,10 @@ def start_douyin_youtube_ffplay(
|
||||
rtmps_base = "rtmps://a.rtmp.youtube.com/live2/"
|
||||
rtmp_base = "rtmp://a.rtmp.youtube.com/live2/"
|
||||
use_rtmps = True
|
||||
# 720p 竖屏 YouTube 建议 4–6 Mbps,偏低易触发「数据不足/卡顿」提示
|
||||
b_v, maxrate, bufsize = "2800k", "3200k", "5600k"
|
||||
# 720p 竖屏,符合 YouTube 推荐:4–6 Mbps、2s 关键帧、AAC 128k
|
||||
b_v, maxrate, bufsize = "4000k", "4500k", "8000k"
|
||||
stream_key = None
|
||||
fast_audio = True # 默认轻量音频链,必要时可在配置里关闭
|
||||
fast_audio = False # 默认恢复强化音频链,必要时可在配置里开启轻量模式
|
||||
|
||||
if os.path.exists(config_file):
|
||||
config = configparser.ConfigParser()
|
||||
@@ -195,8 +195,8 @@ def start_douyin_youtube_ffplay(
|
||||
v = (v or "").strip()
|
||||
if k == "rtmps" and v.lower() in ("0", "false", "否"):
|
||||
use_rtmps = False
|
||||
elif k == "fast_audio" and v.lower() in ("1", "true", "yes", "是", "开", "on"):
|
||||
fast_audio = True
|
||||
elif k == "fast_audio":
|
||||
fast_audio = v.lower() in ("1", "true", "yes", "是", "开", "on")
|
||||
elif k == "bitrate" and v:
|
||||
try:
|
||||
n = int(v)
|
||||
@@ -342,14 +342,13 @@ def start_douyin_youtube_ffplay(
|
||||
except Exception as e:
|
||||
print(f"[WARN] NVENC 检测失败,回退软件编码: {e}")
|
||||
|
||||
_cpu_n = os.cpu_count() or 4
|
||||
_filter_threads = str(min(2, max(1, _cpu_n // 2)))
|
||||
_filter_threads = "4"
|
||||
|
||||
# ====================== 开源音频处理:背景音乐弱化 + 防版权 ======================
|
||||
_script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
_ffmpeg_cwd = None
|
||||
if fast_audio:
|
||||
print("[INFO] fast_audio=开:轻量音频链(无 arnndn/长 EQ),减轻 CPU 以利 speed≥1.0")
|
||||
print("[INFO] fast_audio=开:使用轻量音频链")
|
||||
_af_chain = "afftdn=nf=-26:tn=1,aresample=async=1:first_pts=0"
|
||||
else:
|
||||
# 优先 RNNoise(arnndn),无模型则用 afftdn;aphaser 相位扰动可干扰 Content ID 指纹
|
||||
@@ -372,7 +371,7 @@ def start_douyin_youtube_ffplay(
|
||||
print("[INFO] 未找到 arnndn 模型,使用 afftdn 降噪(可克隆 richardpl/arnndn-models 到 arnndn-models/)")
|
||||
_af_denoise = "afftdn=nf=-26:tn=1,"
|
||||
|
||||
# 仅在明确需要时才启用重音频链,默认优先保 CPU
|
||||
# 强化版:收紧带通 + 频率偏移 + 音高微调 + 多段 EQ + 相位扰动
|
||||
_af_chain = (
|
||||
_af_denoise
|
||||
+ "highpass=f=200,lowpass=f=3800,"
|
||||
@@ -389,14 +388,13 @@ def start_douyin_youtube_ffplay(
|
||||
+ "aresample=async=1:first_pts=0"
|
||||
)
|
||||
|
||||
# 720p 竖屏低耗档:更低帧率和码率,优先保证 2 路并发可用
|
||||
_video_mid = ["-vsync", "cfr", "-g", "30", "-keyint_min", "30", "-r", "15",
|
||||
_video_mid = ["-vsync", "cfr", "-g", "60", "-keyint_min", "60", "-r", "30",
|
||||
"-bf", "0", "-sc_threshold", "0"]
|
||||
if codec_v == "libx264":
|
||||
_video_mid += ["-x264-params", "force-cfr=1:scenecut=0:open_gop=0:sync-lookahead=0"]
|
||||
# -re:按源时间戳节奏拉流,避免突发过快;不用 realtime/arealtime(输入抖动时易让 YouTube 判为数据不足)
|
||||
_vf_pad = (
|
||||
"fps=15,scale=720:1280:force_original_aspect_ratio=decrease:flags=bilinear,"
|
||||
"fps=30,scale=720:1280:force_original_aspect_ratio=decrease:flags=bilinear,"
|
||||
"pad=720:1280:(ow-iw)/2:(oh-ih)/2:black"
|
||||
)
|
||||
_ffmpeg_pre_input = []
|
||||
|
||||
@@ -18,7 +18,7 @@ class YoutubeRuntimeTests(unittest.TestCase):
|
||||
self.assertEqual(normalize_youtube_video_save_type("ts", "tiktok"), "TS")
|
||||
self.assertEqual(normalize_youtube_video_save_type("unknown", "tiktok"), "TS")
|
||||
|
||||
def test_push_defaults_use_lighter_profile(self) -> None:
|
||||
def test_push_defaults_restore_full_profile(self) -> None:
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from douyin_youtube_ffplay import _load_youtube_push_settings
|
||||
@@ -27,8 +27,10 @@ class YoutubeRuntimeTests(unittest.TestCase):
|
||||
cfg = Path(tmp) / "youtube.ini"
|
||||
cfg.write_text("[youtube]\nkey = abc\n", encoding="utf-8")
|
||||
settings = _load_youtube_push_settings(str(cfg))
|
||||
self.assertEqual(settings["b_v"], "2800k")
|
||||
self.assertTrue(settings["fast_audio"])
|
||||
self.assertEqual(settings["b_v"], "4000k")
|
||||
self.assertEqual(settings["maxrate"], "4500k")
|
||||
self.assertEqual(settings["bufsize"], "8000k")
|
||||
self.assertFalse(settings["fast_audio"])
|
||||
|
||||
def test_arm_falls_back_from_vaapi_to_v4l2m2m(self) -> None:
|
||||
enc, note = resolve_live_video_encoder(
|
||||
|
||||
Reference in New Issue
Block a user