else:
    # ====================== 抖音→YouTube 2025（终极精简版） ======================
    import queue
    import time
    import datetime
    import subprocess
    import threading
    import unicodedata
    import platform
    import re
    import traceback

    # --------------------- 配置区（可外部传入） ---------------------
    YT_STREAM_KEY = "qxvb-r47b-r5ju-6ud3-6k7z"
    YOUTUBE_RTMP = f"rtmp://a.rtmp.youtube.com/live2/{YT_STREAM_KEY}"

    MAX_RETRY_DELAY = 90
    INITIAL_RETRY_DELAY = 3
    NO_FRAME_TIMEOUT = 120          # 超过多久无新帧视为下播
    START_CHECK_AFTER = 25.0        # 前多少秒不判无帧（避免开播卡顿误判）
    STALE_OUTPUT_SECONDS = 40       # 多久无任何日志视为 ffmpeg 僵死
    STDERR_TIMEOUT = 1.0

    END_KEYWORDS = [
        "connection reset by peer", "failed to write trailer", "invalid data found",
        "server returned 403", "server returned 404", "ingestion error", "access denied",
        "packet too short", "client disconnected", "live has ended", "no route to host",
        "connection timed out", "connection refused"
    ]

    DOUYIN_HEADERS = (
        "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 18_1 like Mac OS X) AppleWebKit/605.1.15\r\n"
        "Referer: https://live.douyin.com/\r\n"
        "Origin: https://live.douyin.com\r\n"
    )

    # --------------------- 工具函数 ---------------------
    def sanitize_title(text: str, max_len: int = 120) -> str:
        if not text:
            return ""
        text = unicodedata.normalize("NFKC", text)
        text = ''.join(c for c in text if unicodedata.category(c)[0] != 'C')
        text = ''.join(c for c in text if ord(c) <= 0xFFFF)
        return text.strip()[:max_len]

    def detect_nvenc() -> tuple[str, str, list[str]]:
        """返回 (codec, preset, extra_params)"""
        if platform.system().lower() not in ("windows", "linux"):
            return "libx264", "veryfast", ["-tune", "zerolatency"]

        try:
            if subprocess.run(["nvidia-smi"], capture_output=True, timeout=5).returncode != 0:
                return "libx264", "veryfast", ["-tune", "zerolatency"]

            result = subprocess.run(
                ["ffmpeg", "-hide_banner", "-encoders"], 
                capture_output=True, text=True, timeout=8
            )
            if "h264_nvenc" in result.stdout:
                print("[INFO] 检测到 NVIDIA GPU → 使用 NVENC 硬件加速")
                return "h264_nvenc", "p5", ["-tune", "ll", "-rc", "vbr", "-cq", "21", "-b:v", "2500k"]
        except Exception as e:
            print(f"[WARN] NVENC 检测失败，回落软件编码: {e}")
        return "libx264", "veryfast", ["-tune", "zerolatency"]

    def build_ffmpeg_command(real_url: str):
        codec_v, preset_v, tune_params = detect_nvenc()
        return [
            "ffmpeg", "-y", "-loglevel", "info",
            "-rw_timeout", "15000000",
            "-reconnect", "1", "-reconnect_at_eof", "1", "-reconnect_streamed", "1",
            "-reconnect_delay_max", "15",
            "-fflags", "+genpts+discardcorrupt", "-err_detect", "ignore_err",
            "-thread_queue_size", "8192",
            "-headers", DOUYIN_HEADERS,
            "-i", real_url,
            "-vf", "scale=720:1280:force_original_aspect_ratio=decrease,pad=720:1280:(ow-iw)/2:(oh-ih)/2:black",
            "-c:v", codec_v, "-preset", preset_v, *tune_params,
            "-b:v", "2500k", "-maxrate", "2500k", "-bufsize", "5000k",
            "-g", "50", "-r", "25", "-pix_fmt", "yuv420p",
            "-c:a", "aac", "-b:a", "128k", "-ar", "44100", "-ac", "2",
            "-af", "aresample=async=1:first_pts=0",
            "-flags", "+global_header",
            "-f", "flv", YOUTUBE_RTMP
        ]

    # --------------------- 标题生成 ---------------------
    timestamp_str = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
    clean_title = sanitize_title(title_in_name)
    stream_title = sanitize_title(f"{anchor_name}{('_' + clean_title) if clean_title else ''}_{timestamp_str}")
    print(f"[INFO] {rec_info} 开始推流到 YouTube: {stream_title}")

    # --------------------- 主逻辑（单层循环 + 单一 finally） ---------------------
    proc = None
    reader_thread = None
    should_exit = False    # 替代 StreamEnded 异常
    retry_delay = INITIAL_RETRY_DELAY

    def cleanup_resources():
        """统一清理（只调用一次）"""
        nonlocal proc, reader_thread
        if proc and proc.poll() is None:
            try: proc.terminate(); proc.wait(timeout=5)
            except: proc.kill()
        if reader_thread and reader_thread.is_alive():
            reader_thread.join(timeout=1)

        # 全局状态清理（只执行一次）
        try:
            recording.discard(record_name)
            recording_time_list.pop(record_name, None)
            if record_url in running_list:
                running_list.remove(record_url)
            global monitoring
            monitoring = max(0, monitoring - 1)
            clear_record_info(record_name, record_url)
        except: pass

    try:
        ffmpeg_cmd = build_ffmpeg_command(real_url)

        while not should_exit:
            if retry_delay > INITIAL_RETRY_DELAY:
                print(f"[WARN] 防风控等待 {retry_delay}s 后重新连接...")
                time.sleep(retry_delay)

            # 清理上一次的残留
            cleanup_resources()
            proc = None
            reader_thread = None

            stderr_q = queue.Queue()

            print(f"[INFO][{datetime.datetime.now():%H:%M:%S}] 启动 YouTube 推流 → {stream_title}")
            proc = subprocess.Popen(
                ffmpeg_cmd,
                stdin=subprocess.DEVNULL,
                stdout=subprocess.DEVNULL,
                stderr=subprocess.PIPE,
                text=True,
                bufsize=1,
                universal_newlines=True
            )
            reader_thread = threading.Thread(
                target=lambda p=proc, q=stderr_q: (
                    [q.put(l) for l in iter(p.stderr.readline, "")] or q.put(None)
                )
            )
            reader_thread.daemon = True
            reader_thread.start()

            start_time = last_frame_time = last_log_time = time.time()

            while True:
                try:
                    line = stderr_q.get(timeout=STDERR_TIMEOUT)
                except queue.Empty:
                    # 超时检查僵死
                    if time.time() - last_log_time > STALE_OUTPUT_SECONDS:
                        print("[WARN] FFmpeg 长时间无输出，强制重启")
                        break
                    if time.time() - start_time > START_CHECK_AFTER and time.time() - last_frame_time > NO_FRAME_TIMEOUT:
                        print(f"[INFO] 连续 {NO_FRAME_TIMEOUT}s 无新帧，判定主播已下播")
                        should_exit = True
                        break
                    continue

                if line is None:  # stderr 关闭
                    break

                line = line.rstrip()
                if line:
                    last_log_time = time.time()
                    print(f"[FFmpeg] {line}")

                    lower = line.lower()
                    if any(kw in lower for kw in END_KEYWORDS):
                        print("[INFO] 检测到主播真下播关键字，停止转推")
                        should_exit = True
                        break

                    if re.search(r'frame=\s*\d+', lower) or "fps=" in lower:
                        last_frame_time = time.time()

            # 内层循环退出：判断是否真下播
            if should_exit:
                break

            # 网络波动等情况 → 指数退避重试
            retry_delay = min(retry_delay * 2, MAX_RETRY_DELAY)

        # --------------------- 正常退出 ---------------------
        color_obj.print_colored(f"[{record_name}] YouTube 推流已彻底停止并清理完毕\n", color_obj.GREEN)

    except Exception as e:
        print(f"[FATAL] YouTube 推流意外崩溃: {e}")
        traceback.print_exc()
        color_obj.print_colored(f"[{record_name}] YouTube 推流异常退出但已清理\n", color_obj.RED)

    finally:
        # 无论如何只清理一次
        cleanup_resources()
        return