import platform
import time
import datetime
import subprocess

# ====================== 抖音 → YouTube 转推核心代码（终极稳定版）======================
try:
    # 时间戳和标题设置
    timestamp_str = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
    title_suffix = f"_{title_in_name}" if title_in_name else ""
    stream_title = f"{anchor_name}{title_suffix}_{timestamp_str}"

    # 你的 YouTube 推流密钥（请务必换成自己的！）
    YT_STREAM_KEY = "x04z-564w-aks7-embw-30y4"   # food频道
    youtube_rtmp = f"rtmp://a.rtmp.youtube.com/live2/{YT_STREAM_KEY}"

    print(f"{rec_info} 开始推流到 YouTube: {stream_title}")

    # ----------------- 自动检测并启用 NVENC（有N卡就硬件加速）-----------------
    codec_v = "libx264"
    preset_v = "veryfast"
    tune_param = ["-tune", "zerolatency"]
    try:
        if platform.system().lower() in ["windows", "linux"]:
            check = subprocess.run(["nvidia-smi"], capture_output=True, timeout=8)
            if check.returncode == 0:
                enc = subprocess.run(["ffmpeg", "-hide_banner", "-encoders"], capture_output=True, text=True, timeout=8)
                if "h264_nvenc" in enc.stdout:
                    codec_v = "h264_nvenc"
                    preset_v = "p5"
                    tune_param = ["-tune", "ll", "-rc", "vbr", "-cq", "23"]
                    print("检测到 NVIDIA GPU → 使用 NVENC 硬件加速")
    except Exception as e:
        print(f"NVENC检测异常: {e}，使用CPU编码")

    # ----------------- FFmpeg 推流命令（已极致优化）-----------------
    ffmpeg_command = [
        "ffmpeg",
        "-rw_timeout", "15000000",
        "-reconnect", "1",
        "-reconnect_at_eof", "1",
        "-reconnect_streamed", "1",
        "-reconnect_delay_max", "8",
        "-fflags", "+genpts+discardcorrupt+igndts",
        "-err_detect", "ignore_err",
        "-thread_queue_size", "2048",
        "-analyzeduration", "3000000",
        "-probesize", "3000000",
        "-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_param,
        "-b:v", "2500k", "-maxrate", "2500k", "-bufsize", "5000k",
        "-g", "50", "-r", "25", "-pix_fmt", "yuv420p", "-bf", "0",
        "-c:a", "aac", "-b:a", "128k", "-ar", "44100", "-ac", "2",
        "-af", "aresample=async=1:first_pts=0",
        "-flags", "+low_delay+global_header",
        "-fflags", "+genpts+nobuffer",
        "-threads", "8",
        "-f", "flv", youtube_rtmp
    ]

    proc = None
    start_time = time.time()        # 本次推流开始时间

    while True:
        try:
            # 清理上一次残留进程
            if proc and proc.poll() is None:
                proc.terminate()
                try: proc.wait(timeout=6)
                except: proc.kill()

            print(f"[{datetime.datetime.now().strftime('%H:%M:%S')}] 启动YouTube推流 → {stream_title}")
            proc = subprocess.Popen(
                ffmpeg_command,
                stdin=subprocess.DEVNULL,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                bufsize=1,
                universal_newlines=True
            )

            # 时间戳属性
            proc.last_out_ts = time.time()
            last_frame_time = time.time()          # ← 关键：最后一帧时间
            consecutive_404_count = 0

            # ====================== 核心循环（已加入YouTube救命机制）======================
            while True:
                line = proc.stderr.readline()
                if line == '' and proc.poll() is not None:
                    break
                if not line:
                    time.sleep(0.01)
                    continue

                line = line.strip()
                if line:
                    proc.last_out_ts = time.time()

                    # 检测到新帧就刷新时间（最准确的标志
                    if "frame=" in line or "fps=" in line:
                        last_frame_time = time.time()

                    print(f"FFmpeg: {line}")

                line_lower = line.lower()

                # 404 连续计数（8次真下播）
                is_404 = "404" in line_lower and ("not found" in line_lower or "http @" in line_lower)
                if is_404:
                    consecutive_404_count += 1
                    print(f"【404计数】第 {consecutive_404_count} 次（连续8次即退出）")
                    if consecutive_404_count >= 8:
                        print("【真下播】连续8次404，直播已结束，停止推流")
                        if proc and proc.poll() is None:
                            proc.kill()
                        break
                # 不清零

                # 致命错误直接退出
                if any(kw in line_lower for kw in [
                    "403 forbidden", "401 unauthorized", "members only",
                    "private video", "live stream ended", "ingestion error"
                ]):
                    print("【致命错误】检测到封禁/私密/下播，立即停止推流")
                    if proc and proc.poll() is None:
                        proc.kill()
                    break

                # YouTube救命机制：12秒无新帧就必须处决！（YouTube最多忍15~20秒）
                if time.time() - start_time > 25:                              # 25秒后进入战斗模式
                    if time.time() - last_frame_time > 12:                     # 12秒没新帧 → 立刻重启
                        print(f"【YouTube救命】已 {time.time()-last_frame_time:.1f}秒无新帧，立即重启FFmpeg避免直播被杀！")
                        if proc and proc.poll() is None:
                            proc.kill()
                        break

                # 双保险：20秒完全没日志输出也处决
                if time.time() - start_time > 20:
                    if time.time() - proc.last_out_ts > 20:
                        print("【真死流】20秒无任何输出，强制重启进程")
                        if proc and proc.poll() is None:
                            proc.kill()
                        break

            # 进程退出判断
            returncode = proc.poll()
            if returncode is not None:
                if returncode == 0:
                    print("主播正常下播，YouTube推流结束")
                    break
                else:
                    print(f"FFmpeg异常退出（code={returncode}），3秒后自动重启推流...")
                    time.sleep(3)
                    continue

        except Exception as e:
            print(f"推流过程中出现异常: {e}")
            time.sleep(5)
            continue

    # ====================== 彻底清理 ======================
    if proc and proc.poll() is None:
        print("发现残留FFmpeg进程，执行kill")
        proc.kill()

    try: recording.discard(record_name)
    except: pass
    try: recording_time_list.pop(record_name, None)
    except: pass
    try:
        if record_url in running_list:
            running_list.remove(record_url)
            monitoring = max(0, monitoring - 1)
    except: pass
    try: clear_record_info(record_name, record_url)
    except: pass

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

except Exception as e:
    print(f"推流最外层异常: {e}")
    try:
        if 'proc' in locals() and proc and proc.poll() is None:
            proc.kill()
    except: pass
    try:
        recording.discard(record_name)
        recording_time_list.pop(record_name, None)
        if record_url in running_list:
            running_list.remove(record_url)
            monitoring = max(0, monitoring - 1)
        clear_record_info(record_name, record_url)
    except: pass
    color_obj.print_colored(f"[{record_name}] 异常退出但已清理完毕\n", color_obj.RED)