This commit is contained in:
eric
2025-09-16 21:45:03 +08:00
parent 8395418a12
commit 89a96faf11
2 changed files with 22 additions and 22 deletions

View File

@@ -9,9 +9,8 @@ import sys
import logging
import platform
import aiohttp
import select
import spider # 你原来的 spider 模块
import stream # 你原来的 stream 模块
import spider # 你的 spider 模块
import stream # 你的 stream 模块
# ----------------- Logging Setup -----------------
logging.basicConfig(
@@ -25,7 +24,7 @@ IS_WINDOWS = platform.system() == "Windows"
# ----------------- Douyin to YouTube Streamer -----------------
class DouyinToYouTubeStreamer:
def __init__(self, bitrate=5000, audio_bitrate=128, resolution='720x1280',
fps=30, gop=60, max_minutes=8, enable_recording=False):
fps=30, gop=60, max_minutes=None, enable_recording=False):
self.push_proc = None
self.record_proc = None
self.stop_flag = threading.Event()
@@ -38,7 +37,7 @@ class DouyinToYouTubeStreamer:
self.room_name = None
self.pushing = False
self.out_file = None
self.max_minutes = max_minutes
self.max_minutes = max_minutes # None 表示无限制
self.enable_recording = enable_recording
os.makedirs("records", exist_ok=True)
@@ -100,7 +99,7 @@ class DouyinToYouTubeStreamer:
]
return cmd
# ----------------- 推流循环(优化版) -----------------
# ----------------- 推流循环 -----------------
def _run_stream_loop(self, real_url, youtube_key):
while not self.stop_flag.is_set():
try:
@@ -124,7 +123,7 @@ class DouyinToYouTubeStreamer:
)
logging.info(f"[{self.room_name}] 本地录制开始: {self.out_file}")
# ---- monitor stderr 阻塞 ----
# ---- monitor stderr 阻塞读取Windows兼容 ----
def monitor_proc(proc, name):
try:
while not self.stop_flag.is_set() and proc and proc.poll() is None:
@@ -144,7 +143,7 @@ class DouyinToYouTubeStreamer:
# ---- 循环检查进程状态 ----
while not self.stop_flag.is_set():
elapsed = time.time() - self.start_time
if elapsed >= self.max_minutes * 60:
if self.max_minutes and elapsed >= self.max_minutes * 60:
logging.warning(f"[{self.room_name}] 超过 {self.max_minutes} 分钟,自动停止推流和录制")
self.stop()
break
@@ -158,6 +157,8 @@ class DouyinToYouTubeStreamer:
time.sleep(5)
break
time.sleep(2)
except Exception as e:
logging.error(f"[{self.room_name}] FFmpeg异常: {e}")
finally:
@@ -238,7 +239,6 @@ async def get_douyin_real_url(record_url, record_quality="原画", proxy_addr=No
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, enable_recording=False):
real_url = asyncio.run(get_douyin_real_url(record_url, proxy_addr=proxy_addr, cookies=cookies))
@@ -246,14 +246,14 @@ def start_douyin_to_youtube(record_url, youtube_key, room_name=None,
logging.error("获取真实直播流失败")
return None
logging.info(f"实际直播流: {real_url}")
streamer = DouyinToYouTubeStreamer(bitrate=bitrate, enable_recording=enable_recording)
streamer = DouyinToYouTubeStreamer(bitrate=bitrate, enable_recording=enable_recording, max_minutes=None)
streamer.start_stream(real_url, youtube_key, room_name)
return streamer
# ----------------- Main Program -----------------
if __name__ == "__main__":
DOUYIN_URL = "https://live.douyin.com/722725928418"
DOUYIN_URL = "https://live.douyin.com/851742623054"
YOUTUBE_KEY = "qxvb-r47b-r5ju-6ud3-6k7z"
# enable_recording=True 可开启本地录制

22
live.py
View File

@@ -9,9 +9,8 @@ import sys
import logging
import platform
import aiohttp
import select
import spider # 你原来的 spider 模块
import stream # 你原来的 stream 模块
import spider # 你的 spider 模块
import stream # 你的 stream 模块
# ----------------- Logging Setup -----------------
logging.basicConfig(
@@ -25,7 +24,7 @@ IS_WINDOWS = platform.system() == "Windows"
# ----------------- Douyin to YouTube Streamer -----------------
class DouyinToYouTubeStreamer:
def __init__(self, bitrate=5000, audio_bitrate=128, resolution='720x1280',
fps=30, gop=60, max_minutes=8, enable_recording=False):
fps=30, gop=60, max_minutes=None, enable_recording=False):
self.push_proc = None
self.record_proc = None
self.stop_flag = threading.Event()
@@ -38,7 +37,7 @@ class DouyinToYouTubeStreamer:
self.room_name = None
self.pushing = False
self.out_file = None
self.max_minutes = max_minutes
self.max_minutes = max_minutes # None 表示无限制
self.enable_recording = enable_recording
os.makedirs("records", exist_ok=True)
@@ -100,7 +99,7 @@ class DouyinToYouTubeStreamer:
]
return cmd
# ----------------- 推流循环(优化版) -----------------
# ----------------- 推流循环 -----------------
def _run_stream_loop(self, real_url, youtube_key):
while not self.stop_flag.is_set():
try:
@@ -124,7 +123,7 @@ class DouyinToYouTubeStreamer:
)
logging.info(f"[{self.room_name}] 本地录制开始: {self.out_file}")
# ---- monitor stderr 阻塞 ----
# ---- monitor stderr 阻塞读取Windows兼容 ----
def monitor_proc(proc, name):
try:
while not self.stop_flag.is_set() and proc and proc.poll() is None:
@@ -144,7 +143,7 @@ class DouyinToYouTubeStreamer:
# ---- 循环检查进程状态 ----
while not self.stop_flag.is_set():
elapsed = time.time() - self.start_time
if elapsed >= self.max_minutes * 60:
if self.max_minutes and elapsed >= self.max_minutes * 60:
logging.warning(f"[{self.room_name}] 超过 {self.max_minutes} 分钟,自动停止推流和录制")
self.stop()
break
@@ -158,6 +157,8 @@ class DouyinToYouTubeStreamer:
time.sleep(5)
break
time.sleep(2)
except Exception as e:
logging.error(f"[{self.room_name}] FFmpeg异常: {e}")
finally:
@@ -238,7 +239,6 @@ async def get_douyin_real_url(record_url, record_quality="原画", proxy_addr=No
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, enable_recording=False):
real_url = asyncio.run(get_douyin_real_url(record_url, proxy_addr=proxy_addr, cookies=cookies))
@@ -246,14 +246,14 @@ def start_douyin_to_youtube(record_url, youtube_key, room_name=None,
logging.error("获取真实直播流失败")
return None
logging.info(f"实际直播流: {real_url}")
streamer = DouyinToYouTubeStreamer(bitrate=bitrate, enable_recording=enable_recording)
streamer = DouyinToYouTubeStreamer(bitrate=bitrate, enable_recording=enable_recording, max_minutes=None)
streamer.start_stream(real_url, youtube_key, room_name)
return streamer
# ----------------- Main Program -----------------
if __name__ == "__main__":
DOUYIN_URL = "https://live.douyin.com/722725928418"
DOUYIN_URL = "https://live.douyin.com/402085299686"
YOUTUBE_KEY = "qxvb-r47b-r5ju-6ud3-6k7z"
# enable_recording=True 可开启本地录制