15 Commits

Author SHA1 Message Date
Your Name
2375331973 srs-mpv 2026-01-02 04:37:59 +00:00
Your Name
041a402a73 mpv-grok 2025-12-30 14:00:02 +00:00
Your Name
a7b7761e78 lajilaji 2025-12-30 10:03:08 +00:00
Your Name
7ac4c7ff90 mpv设计ok 2025-12-30 06:42:07 +00:00
Your Name
d4158e7f1a mpv断线重启 2025-12-30 06:28:06 +00:00
Your Name
8953e2f4d4 ffmpeg=>pipe=>mpv 2025-12-30 04:37:35 +00:00
Your Name
88d54c1679 mpv检测第1版 2025-12-30 02:40:13 +00:00
Your Name
c630787719 mpv初始版本 2025-12-30 01:50:28 +00:00
Your Name
67bacc1c42 s 2025-12-29 06:11:30 +00:00
eric
53f2c77421 's' 2025-12-28 08:45:14 -06:00
eric
9107995c02 ';s' 2025-12-28 08:20:11 -06:00
eric
3ff4facd3d 's' 2025-12-28 07:52:07 -06:00
eric
34bb2b661e 's' 2025-12-28 07:50:05 -06:00
eric
6aeb1462dd 's' 2025-12-23 06:47:50 -06:00
eric
0c7437f9cc 's' 2025-12-20 09:30:30 -06:00
3 changed files with 159 additions and 348 deletions

View File

@@ -1,5 +1,13 @@
https://live.douyin.com/456576000931,主播: 介休〖烩饕〗大块牛肉饭「摆摊」
https://live.douyin.com/272489828538,主播: 90后摆摊卖肉夹馍
https://live.douyin.com/9638535297,主播: 异度世界
https://live.douyin.com/372551154040,主播: 向嘉_手打柠檬茶
https://live.douyin.com/203476627795,主播: 蜜桃姐姐(手打柠檬茶)
https://live.douyin.com/825627287092,主播: 杏绘茶档_(00后创业版_手打柠檬茶)
https://live.douyin.com/147650297461,主播: 娱乐摆摊记
https://live.douyin.com/806666144080,主播: 卢荟胶
https://live.douyin.com/589958309143,主播: 大萝卜
https://live.douyin.com/35932729226,主播: 内向小学生
https://live.douyin.com/456576000931,主播: 介休〖烩饕〗大块牛肉饭「摆摊」
https://live.douyin.com/782322393954,主播: 小葵(摆摊版)
https://live.douyin.com/208318182053,主播: 小碗(创业版)
https://live.douyin.com/646935372639,主播: 小雪摆摊记
https://live.douyin.com/956877163856,主播: 饭饱饱
@@ -7,54 +15,16 @@ https://live.douyin.com/881451071780,主播: YINING一柠手打柠檬茶
https://live.douyin.com/270513395244,主播: 小喻的摆摊日记
https://live.douyin.com/742474761291,主播: 阿诺椰子•
https://live.douyin.com/820845121901,主播: 地摊闺蜜_创意寿司_(马儿努力版)
https://live.douyin.com/980855021360,主播: 图爸摆摊卖枣糕(日照首家)教学员
https://live.douyin.com/46238285118,主播: 我叫小彤呀
https://live.douyin.com/497155982953,主播: 想吃糖葫芦
https://live.douyin.com/349973241990,主播: 元气满满饭团(摆摊不摆烂版)
https://live.douyin.com/814839174401,主播: 飞飞摆摊不摆烂
https://live.douyin.com/597618993066,主播: 婷婷的茶生活
https://live.douyin.com/782322393954,主播: 小葵(摆摊版)
https://live.douyin.com/16531926455,主播: 木黎黎
https://live.douyin.com/739670432305,主播: 干饭007
https://live.douyin.com/486789870173,主播: 凉皮西施—豆豆
https://live.douyin.com/15652099787,主播: 莹莹在摆摊
https://live.douyin.com/572442812068,主播: 小小
https://live.douyin.com/477961427964,主播: 小鱼
https://live.douyin.com/686507122231,主播: 上海少妇鲜果茶
https://live.douyin.com/50627104055,主播: 冷阿姨
https://live.douyin.com/339454333072,主播: 小安炒粉
https://live.douyin.com/72212955083,主播: 花老板回村了
https://live.douyin.com/280422307519,主播: 早餐妹
https://live.douyin.com/651293616593,主播: 会發的黄
https://live.douyin.com/114111936890,主播: 小乖早安_(小七泡面)
https://live.douyin.com/43665279648,主播: 喵喵老师
https://live.douyin.com/122383435921,主播: 婷饱饱
https://live.douyin.com/92876979328,主播: 福宝(野摊小馄饨)
https://live.douyin.com/517715534931,主播: 一只羊
https://live.douyin.com/460525712926,主播: 丽姐摆摊记
https://live.douyin.com/745606325880,主播: w、(摆摊日记_)
https://live.douyin.com/675343045974,主播: 张子沐的串串(你的电子榨菜)
https://live.douyin.com/673565298571,主播: 轻舟已撞大冰山(摆摊vlog)
https://live.douyin.com/835571459859,主播: 海绵饱饱
https://live.douyin.com/152358755212,主播: 大美_红烧肉
https://live.douyin.com/990825651731,主播: 王同学摆摊日记(蜜汁烤鸡腿)
https://live.douyin.com/591442402624,主播: 76696515302
https://live.douyin.com/967381081829,主播: 憨憨的摆摊日记
https://live.douyin.com/78012762575,主播: 摆摊儿去划水
https://live.douyin.com/163813589919,主播: 不要熬夜(摆摊中)
https://live.douyin.com/498368994814,主播: 剪头发的小帆帆
https://live.douyin.com/617848099204,主播: 果妈要努力
https://live.douyin.com/821525628944,主播: 李熙雨⭐
https://live.douyin.com/993102287144,主播: 小茗早餐(薪笼记助创官)
https://live.douyin.com/701547125568,主播: 悠悠包
https://live.douyin.com/816130992220,主播: 甜昕冰冰的摆摊日记
https://live.douyin.com/876468215361,主播: 晓晓和凡凡
https://live.douyin.com/511335278313,主播: 秘书(摆摊休息版)
https://live.douyin.com/483160615952,主播: 小胡同学你好(饭团版)
https://live.douyin.com/525514386431,主播: 阿闯烤肉夹馍
https://live.douyin.com/8687122573,主播: 小彤炒粉
https://live.douyin.com/642534242822,主播: (小王_)煎饼果子
https://live.douyin.com/743565594721,主播: 汪汪汪小妞
https://live.douyin.com/249578288248,主播: 思思努力版
https://live.douyin.com/472140253414,主播: 戴盘龙
https://live.douyin.com/700846653732,主播: 三哥大锅菜_炒鸡(国基路店)官方号
https://live.douyin.com/81849868631,主播: 纯儿²¹(休息勿跑空哦)
https://live.douyin.com/690114366322,主播: 卤味鲜(东大)
https://live.douyin.com/469980190666,主播: 茜茜柠檬茶(小米茶档_)
https://live.douyin.com/388066418744,主播: 加速姐的摆摊日记

387
main.py
View File

@@ -1164,11 +1164,9 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None:
push_at = datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S')
if port_info['is_live'] is False:
print(f"\r{record_name} 等待直播... ")
# 直接退出线程eric
# return
# 继续循环
continue
# continue # 继续循环
return # 线程彻底退出
if start_pushed:
if over_show_push:
@@ -1622,16 +1620,22 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None:
error_window.append(1)
else:
# ====================== 抖音→YouTube 2025重构单层重试 + 统一清理) ======================
import queue, unicodedata, platform, traceback
# ====================== 抖音 → SRS → ffplay HDMI 终极低CPU清晰版 ======================
import queue
import unicodedata
import traceback
# import time
# import datetime
# import subprocess
# import threading
# import re
class StreamEnded(Exception):
pass
def sanitize_title(text: str, max_len: int = 120) -> str:
if not text: return ""
if not text:
return ""
text = unicodedata.normalize("NFKC", text)
text = ''.join(ch for ch in text if unicodedata.category(ch)[0] != 'C')
text = ''.join(ch for ch in text if ord(ch) <= 0xFFFF)
@@ -1644,229 +1648,122 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None:
if not line:
break
q.put(line)
except Exception as e:
try:
q.put(f"__ERR__READER__:{e}")
except Exception:
except:
pass
finally:
try:
q.put(None)
except Exception:
except:
pass
def cleanup_proc(proc):
try:
def cleanup_proc(proc, name="进程"):
if proc and proc.poll() is None:
try:
proc.terminate()
proc.wait(timeout=5)
except Exception:
if proc.poll() is None:
try:
proc.wait(timeout=8)
except subprocess.TimeoutExpired:
proc.kill()
except Exception:
pass
except Exception:
pass
except:
proc.kill()
print(f"[INFO] 已强制终止 {name}")
# ========== 参数配置(保留你原始配置) ==========
# YT_STREAM_KEY = "qxvb-r47b-r5ju-6ud3-6k7z"
youtube_rtmp = f"rtmp://a.rtmp.youtube.com/live2/x04z-564w-aks7-embw-30y4"
# youtube_rtmp="rtmp://192.168.31.184/live/douyin"
# ====================== 配置参数 ======================
SRS_RTMP_URL = "rtmp://127.0.0.1/live/douyin"
SRS_PLAY_URL = "http://127.0.0.1:8080/live/douyin.flv"
# # ←←←← 在这块代码的上方先定义你要推的多个地址 ←←←←
# rtmp_targets = [
# "rtmp://a.rtmp.youtube.com/live2/qxvb-r47b-r5ju-6ud3-6k7z", # 主频道
# "rtmp://192.168.31.184/live/douyin", # 备用频道(换成你的第二个 YouTube 密钥)
# ]
# # 用 | 拼接所有地址(任何一个断开都不会影响其他)
# tee_outputs = "|".join([f"[f=flv]{url}" for url in rtmp_targets])
MAX_RETRY_DELAY = 90
MAX_RETRY_DELAY = 120
INITIAL_RETRY_DELAY = 3
STDERR_QUEUE_TIMEOUT = 1.0
NO_FRAME_TIMEOUT = 120
START_CHECK_AFTER = 25
STALE_OUTPUT_SECONDS = 120 #120
NO_FRAME_TIMEOUT = 180
STALE_OUTPUT_SECONDS = 180
FFPLAY_RESTART_INTERVAL = 3600 * 6
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 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",
]
timestamp_str = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
_clean_title_in_name = sanitize_title(title_in_name)
stream_title = sanitize_title(f"{anchor_name}{('_' + _clean_title_in_name) if _clean_title_in_name else ''}_{timestamp_str}")
print(f"[INFO] {rec_info} 开始推流到 YouTube: {stream_title}")
_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} 启动 SRS → ffplay HDMI 转播低CPU原画版: {stream_title}")
# NVENC 检测(原样保留)
codec_v, preset_v, tune_param = "libx264", "veryfast", ["-tune", "zerolatency"]
try:
if platform.system().lower() in ["windows", "linux"]:
check = subprocess.run(["nvidia-smi"], capture_output=True, timeout=5)
if check.returncode == 0:
enc = subprocess.run(["ffmpeg", "-hide_banner", "-encoders"], capture_output=True, text=True, timeout=5)
if "h264_nvenc" in (enc.stdout or ""):
codec_v, preset_v, tune_param = "h264_nvenc", "p5", ["-tune", "ll", "-rc", "vbr", "-cq", "21", "-b:v", "2500k"]
print("[INFO] 检测到 NVIDIA GPU → 使用 NVENC 硬件加速")
except Exception as e:
print(f"[WARN] NVENC 检测失败,回退软件编码: {e}")
# headers & ffmpeg command保持原来参数
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"
)
# 720p
# ffmpeg_command = [
# "ffmpeg", "-y", "-loglevel", "info", "-nostdin", "-re",
# "-stats", "-stats_period", "1",
# "-rw_timeout", "30000000",
# "-reconnect", "1", "-reconnect_at_eof", "1", "-reconnect_streamed", "1",
# "-reconnect_delay_max", "5",
# "-fflags", "+genpts+discardcorrupt+nobuffer+flush_packets",
# "-flags", "low_delay",
# "-err_detect", "ignore_err",
# "-max_delay", "80000",
# "-thread_queue_size", "2048",
# "-headers", douyin_headers,
# "-i", real_url,
# # 720p
# "-vf", "fps=30,scale=720:1280:force_original_aspect_ratio=decrease:flags=lanczos,pad=720:1280:(ow-iw)/2:(oh-ih)/2:black",
# "-c:v", "libx264",
# "-preset", "fast",
# # "-tune", "zerolatency",
# "-profile:v", "high",
# # 720p
# # "-minrate", "3200k","-b:v", "3200k", "-maxrate", "3200k", "-bufsize", "6400k", # bufsize = 2× bitrate保持真 CBR
# "-b:v", "2600k","-maxrate", "3000k","-bufsize", "5200k",
# "-vsync", "cfr",
# "-g", "60", "-keyint_min", "60",
# "-r", "30",
# "-bf", "0",
# "-sc_threshold", "0",
# # "-nal-hrd", "cbr", # 改2强制 CBR
# # 720p
# # "-x264-params", "nal-hrd=cbr:force-cfr=1:scenecut=0:filler=1", # 改3简化 params锁死 CBR
# "-x264-params", "force-cfr=1:scenecut=0:open_gop=0:sync-lookahead=0",
# "-pix_fmt", "yuv420p",
# "-c:a", "aac", "-b:a", "128k", "-ar", "48000", "-ac", "2", # 改41080p可音频上 128kYouTube 推荐)
# "-af", "aresample=async=1:first_pts=0",
# "-flags", "+global_header",
# "-flvflags", "no_duration_filesize",
# "-f", "flv", youtube_rtmp
# ]
# 1080p
# ====================== FFmpeg 推流到 SRS直抄原画低CPU ======================
ffmpeg_command = [
"ffmpeg", "-y", "-loglevel", "info", "-nostdin", "-re",
"-stats", "-stats_period", "1",
"ffmpeg", "-y", "-loglevel", "info", "-nostdin",
"-headers", douyin_headers,
"-rw_timeout", "30000000",
"-reconnect", "1", "-reconnect_at_eof", "1", "-reconnect_streamed", "1",
"-reconnect_delay_max", "5",
"-fflags", "+genpts+discardcorrupt+nobuffer+flush_packets",
"-flags", "low_delay",
"-reconnect_delay_max", "7",
"-fflags", "+genpts+discardcorrupt+igndts",
"-err_detect", "ignore_err",
"-max_delay", "80000",
"-thread_queue_size", "2048",
"-headers", douyin_headers,
"-i", real_url,
# 1080p
"-vf","fps=30,scale=1080:1920:force_original_aspect_ratio=decrease:flags=lanczos,pad=1080:1920:(ow-iw)/2:(oh-ih)/2:black",
"-c:v", "libx264",
"-preset", "veryfast",
"-tune", "zerolatency",
"-profile:v", "high",
# 1080p
"-b:v", "5200k", "-maxrate", "5800k", "-bufsize", "10400k", # 改12× bufsize真 CBR
"-vsync", "cfr",
"-g", "60", "-keyint_min", "60",
"-r", "30",
"-bf", "0",
"-sc_threshold", "0",
# "-nal-hrd", "cbr", # 改2强制 CBR
# 1080p
"-x264-params","force-cfr=1:scenecut=0:open_gop=0:sync-lookahead=0",
"-pix_fmt", "yuv420p",
"-c:a", "aac", "-b:a", "128k", "-ar", "44100", "-ac", "2",
"-af", "aresample=async=1:first_pts=0",
"-flags", "+global_header",
"-flvflags", "no_duration_filesize",
"-f", "flv", youtube_rtmp
"-c:v", "copy", # 直抄视频CPU极低画质取决于源抖音通常给原画
"-c:a", "copy", # 直抄音频
"-f", "flv", SRS_RTMP_URL
]
# ====================== ffplay 最佳参数低CPU + 零漂移 + 全屏) ======================
ffplay_cmd = [
"ffplay",
"-fflags", "nobuffer+genpts",
"-flags", "low_delay",
"-framedrop",
"-sync", "ext", # 零漂移
"-vf", "transpose=2", # 旋转
"-autoexit",
"-fs", # 全屏
"-loglevel", "quiet",
"-i", SRS_PLAY_URL
]
# srs内网配置
# ffmpeg_command = [
# "ffmpeg",
# "-loglevel", "info",
# "-err_detect", "ignore_err+explode",
# "-fflags", "+genpts+discardcorrupt+igndts",
# "-reconnect", "1",
# "-reconnect_at_eof", "1",
# "-reconnect_streamed", "1",
# "-reconnect_delay_max", "7",
# "-rw_timeout", "30000000",
# "-headers", douyin_headers,
# # ===== 输入源 =====
# "-i", real_url,
# "-c:v", "copy",
# "-c:a", "copy",
# "-max_muxing_queue_size", "9999",
# "-f", "flv", srs_rtmp
# ]
# ---- 单层重试循环(清晰可控) ----
proc = None
stderr_q = None
ffmpeg_proc = None
ffplay_proc = None
stderr_q = queue.Queue()
reader_t = None
retry_delay = INITIAL_RETRY_DELAY
last_ffplay_restart = time.time()
try:
while True:
try:
current_time = time.time()
if ffplay_proc and (current_time - last_ffplay_restart > FFPLAY_RESTART_INTERVAL):
print("[SCHEDULE] 6小时预防性重启 ffplay")
cleanup_proc(ffplay_proc, "ffplay")
ffplay_proc = None
if ffplay_proc is None or ffplay_proc.poll() is not None:
if ffplay_proc is not None:
print("[WARN] ffplay 退出,重启中...")
print(f"[INFO][{datetime.datetime.now():%H:%M:%S}] 启动 ffplay 播放 SRS 原画流")
ffplay_proc = subprocess.Popen(
ffplay_cmd,
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
text=True
)
time.sleep(2)
last_ffplay_restart = time.time()
if retry_delay > INITIAL_RETRY_DELAY:
print(f"[WARN] 防风控等待 {retry_delay}s 后重新连接抖音源...")
print(f"[WARN] 等待 {retry_delay}s 后重抖音源...")
time.sleep(retry_delay)
retry_delay = min(retry_delay * 2, MAX_RETRY_DELAY)
# 每次重连前先清理上一次的进程/线程
try:
cleanup_proc(proc)
except Exception:
pass
if stderr_q:
# 垃圾化旧队列以便 GC
stderr_q = None
stderr_q = queue.Queue()
cleanup_proc(ffmpeg_proc, "FFmpeg")
print(f"[INFO][{datetime.datetime.now():%H:%M:%S}] 启动 YouTube 推流 → {stream_title}")
proc = subprocess.Popen(
print(f"[INFO][{datetime.datetime.now():%H:%M:%S}] 启动 FFmpeg 直抄推流到 SRS")
ffmpeg_proc = subprocess.Popen(
ffmpeg_command,
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
@@ -1875,94 +1772,58 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None:
bufsize=1,
universal_newlines=True
)
proc.last_out_ts = time.time()
ffmpeg_proc.last_out_ts = time.time()
# 启动 stderr reader
reader_t = threading.Thread(target=_stderr_reader_thread, args=(proc, stderr_q))
stderr_q = queue.Queue()
reader_t = threading.Thread(target=_stderr_reader_thread, args=(ffmpeg_proc, stderr_q))
reader_t.daemon = True
reader_t.start()
start_time = last_frame_time = time.time()
last_frame_time = time.time()
# ---- 监控循环(单一职责:处理 stderr 日志并决定是否结束/重连) ----
while True:
try:
try:
line = stderr_q.get(timeout=STDERR_QUEUE_TIMEOUT)
line = stderr_q.get(timeout=1.5)
except queue.Empty:
# 超时检查:如果太久没有任何日志,判为僵死,重启 proc跳出内层进行重试
if time.time() - getattr(proc, "last_out_ts", time.time()) > STALE_OUTPUT_SECONDS:
print("[WARN] 长时间无任何日志,强制重启进程")
cleanup_proc(proc)
if time.time() - ffmpeg_proc.last_out_ts > STALE_OUTPUT_SECONDS:
print("[WARN] FFmpeg 僵死,重启")
break
continue
if line is None:
# reader 线程结束;如果 proc 已退出,跳出去重试
if proc.poll() is not None:
break
else:
continue
line = line.strip()
if line.startswith("__ERR__READER__"):
print(f"[ERROR] stderr reader 异常: {line}")
if not line:
continue
if line:
proc.last_out_ts = time.time()
ffmpeg_proc.last_out_ts = time.time()
print(f"[FFmpeg] {line}")
line_lower = line.lower()
# 检测到明确下播关键字 -> 认为主播真下播,立即退出(不再重试)
if any(kw in line_lower for kw in END_KEYWORDS):
print("[ERROR] 检测到主播真下播或被明确拒绝,停止推流")
cleanup_proc(proc)
print("[INFO] 检测到下播关键字,停止转播")
raise StreamEnded()
# 帧检测:更新 frame 时间戳
if re.search(r'frame=\s*\d+', line_lower) or "fps=" in line_lower:
if re.search(r'frame=\s*\d+', line_lower):
last_frame_time = time.time()
retry_delay = INITIAL_RETRY_DELAY
# 超时无新帧 => 认为下播
if time.time() - start_time > START_CHECK_AFTER:
if time.time() - last_frame_time > NO_FRAME_TIMEOUT:
print(f"[WARN] 连续 {NO_FRAME_TIMEOUT}s 无新帧,判定主播已下播")
cleanup_proc(proc)
print(f"[INFO] {NO_FRAME_TIMEOUT}s 无新帧,判定下播")
raise StreamEnded()
except StreamEnded:
# 真实下播,抛到外层处理(最终会退出函数)
raise
print(f"[INFO] 主播已下播,停止 SRS → ffplay HDMI 转播 → {record_name}")
except KeyboardInterrupt:
print("[INFO] 用户手动中断")
except Exception as e:
# 内层非致命异常:打印、回退重试间隔,退出监控循环以在外层重试
print(f"[ERROR] 内层异常: {e}")
print(f"[FATAL] 未知异常: {e}")
traceback.print_exc()
cleanup_proc(proc)
retry_delay = min(retry_delay * 2, MAX_RETRY_DELAY)
break # 跳出监控循环 -> 外层 while 会继续并重试
# 如果监控循环走到这里并不是因为 StreamEnded例如 break则重试连接loop continue
# 将在 while True 的下一次循环中进行等待并重连
continue
except StreamEnded:
# 真实的主播下播,停止并彻底退出本录制线程
print(f"[INFO] 主播已下播,停止 YouTube 转推 → {record_name}")
break
except Exception as e:
# 外层致命异常:打印并退出循环(会在 finally 里做统一清理)
print(f"[ERROR] 外层异常: {e}")
traceback.print_exc()
retry_delay = min(retry_delay * 2, MAX_RETRY_DELAY)
# 等待并尝试重连(除非你希望直接退出,这里保留重试策略)
continue
# ============ 正常或 StreamEnded 后的统一清理(在这里 break 到这里) ============
cleanup_proc(proc)
# 以下清理放在 try/except 里以防止清理过程出错导致漏逻辑
time.sleep(10)
finally:
cleanup_proc(ffmpeg_proc, "FFmpeg")
cleanup_proc(ffplay_proc, "ffplay")
try:
recording.discard(record_name)
recording_time_list.pop(record_name, None)
@@ -1971,36 +1832,18 @@ def start_record(url_data: tuple, count_variable: int = -1) -> None:
global monitoring
monitoring = max(0, monitoring - 1)
clear_record_info(record_name, record_url)
except Exception:
except:
pass
color_obj.print_colored(f"[{record_name}] YouTube 推流已彻底停止并清理完毕\n", color_obj.GREEN)
return
except Exception as e:
# 最外层异常也要统一清理(保证不会留下僵尸状态)
print(f"[FATAL] YouTube 推流最外层异常: {e}")
traceback.print_exc()
try:
cleanup_proc(proc)
except Exception:
pass
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 Exception:
pass
color_obj.print_colored(f"[{record_name}] YouTube 推流异常退出但已清理\n", color_obj.RED)
return
color_obj.print_colored(f"[{record_name}] SRS → ffplay HDMI 转播已彻底停止并清理完毕\n", color_obj.GREEN)
count_time = time.time()
except Exception as e:
logger.error(f"错误信息: {e} 发生错误的行数: {e.__traceback__.tb_lineno}")
with max_request_lock:

View File

@@ -3,9 +3,6 @@ qxvb-r47b-r5ju-6ud3-6k7z # vlog频道
x04z-564w-aks7-embw-30y4 #美食ypp
; https://live.douyin.com/517715534931,主播: 一只羊
; https://live.douyin.com/460525712926,主播: 丽姐摆摊记
; https://live.douyin.com/745606325880,主播: w、(摆摊日记_)
; https://live.douyin.com/675343045974,主播: 张子沐的串串(你的电子榨菜)
; https://live.douyin.com/673565298571,主播: 轻舟已撞大冰山(摆摊vlog)
@@ -36,3 +33,4 @@ x04z-564w-aks7-embw-30y4 #美食ypp
; https://live.douyin.com/690114366322,主播: 卤味鲜(东大)
; https://live.douyin.com/469980190666,主播: 茜茜柠檬茶(小米茶档_)
; https://live.douyin.com/388066418744,主播: 加速姐的摆摊日记