From 94f7939b48d508e1c705468d5f2ce7940cf52aa3 Mon Sep 17 00:00:00 2001 From: eric Date: Tue, 16 Sep 2025 19:28:48 +0800 Subject: [PATCH] 's' --- live.py | 55 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/live.py b/live.py index 6e91a37..7f65b92 100644 --- a/live.py +++ b/live.py @@ -10,6 +10,7 @@ import logging import platform import spider import stream +import aiohttp # ----------------- Logging Setup ----------------- logging.basicConfig( @@ -184,7 +185,6 @@ class DouyinToYouTubeStreamer: def _finalize_recording(self): if self.out_file and os.path.exists(self.out_file): try: - # 根据系统发送信号完成封装 if self.record_proc and self.record_proc.poll() is None: sig = signal.CTRL_BREAK_EVENT if IS_WINDOWS else signal.SIGINT self.record_proc.send_signal(sig) @@ -195,7 +195,6 @@ class DouyinToYouTubeStreamer: except Exception: pass - # 重命名文件带时长 elapsed = int(time.time() - self.start_time) if self.start_time else 0 suffix = f"_{elapsed // 60}min" if elapsed >= 60 else f"_{elapsed}s" new_name = self.out_file.replace(".mp4", f"{suffix}.mp4") @@ -209,22 +208,54 @@ class DouyinToYouTubeStreamer: # ----------------- Douyin Stream Parsing ----------------- async def get_douyin_real_url(record_url, record_quality="原画", proxy_addr=None, cookies=''): + headers = { + "User-Agent": ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36"), + "Referer": "https://www.douyin.com/", + "Origin": "https://www.douyin.com", + "Accept": "application/json, text/javascript, */*; q=0.01", + } + + session_args = {"headers": headers} + if proxy_addr: + session_args["proxy"] = proxy_addr + try: - if 'v.douyin.com' not in record_url and '/user/' not in record_url: - json_data = await spider.get_douyin_stream_data(url=record_url, - proxy_addr=proxy_addr, cookies=cookies) - else: - json_data = await spider.get_douyin_app_stream_data(url=record_url, - proxy_addr=proxy_addr, cookies=cookies) - port_info = await stream.get_douyin_stream_url(json_data, record_quality, proxy_addr) - return port_info.get("record_url") + async with aiohttp.ClientSession(**session_args) as session: + for attempt in range(3): + try: + async with session.get(record_url, cookies=cookies) as resp: + text = await resp.text() + if not text or "captcha" in text.lower(): + logging.warning(f"第{attempt+1}次尝试获取流失败,返回内容为空或验证码,重试...") + await asyncio.sleep(1) + continue + if 'v.douyin.com' not in record_url and '/user/' not in record_url: + json_data = await spider.get_douyin_stream_data( + url=record_url, proxy_addr=proxy_addr, cookies=cookies) + else: + json_data = await spider.get_douyin_app_stream_data( + url=record_url, proxy_addr=proxy_addr, cookies=cookies) + + port_info = await stream.get_douyin_stream_url( + json_data, record_quality, proxy_addr) + if port_info and port_info.get("record_url"): + return port_info.get("record_url") + else: + logging.warning(f"第{attempt+1}次尝试解析失败,port_info为空") + await asyncio.sleep(1) + except Exception as e: + logging.warning(f"第{attempt+1}次尝试抓取抖音流异常: {e}") + await asyncio.sleep(1) + logging.error("多次尝试后仍获取抖音真实流失败") + return None except Exception as e: - logging.error(f"获取抖音真实流失败: {e}") + logging.error(f"初始化 aiohttp session 失败: {e}") return None def start_douyin_to_youtube(record_url, youtube_key, room_name=None, proxy_addr=None, cookies='', bitrate=5000): - real_url = asyncio.run(get_douyin_real_url(record_url, proxy_addr, cookies)) + real_url = asyncio.run(get_douyin_real_url(record_url, proxy_addr=proxy_addr, cookies=cookies)) if not real_url: logging.error("获取真实直播流失败") return None