From 682350c804eb49b0b815d1ac602918a15c84601b Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 14 Sep 2025 08:42:57 +0800 Subject: [PATCH] 's' --- list | 3 ++- live.py | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/list b/list index bdb901f..9a99421 100644 --- a/list +++ b/list @@ -1,2 +1,3 @@ https://live.douyin.com/525514386431 -https://live.douyin.com/8687122573 \ No newline at end of file +https://live.douyin.com/8687122573 +https://live.douyin.com/642534242822 \ No newline at end of file diff --git a/live.py b/live.py index 8c1b1f5..511680b 100644 --- a/live.py +++ b/live.py @@ -11,6 +11,7 @@ import shutil import spider import stream + class AdaptiveHLS2YouTube: def __init__(self, max_bitrate=5000, min_bitrate=3000, audio_bitrate=192, delay_sec=40, segment_time=2, check_interval=5): @@ -19,7 +20,7 @@ class AdaptiveHLS2YouTube: self.delay_sec = delay_sec self.segment_time = segment_time self.check_interval = check_interval - self.buffer_queue = queue.Queue(maxsize=500) # 增大队列,防止阻塞 + self.buffer_queue = queue.Queue(maxsize=800) # 队列加大 self.max_bitrate = max_bitrate self.min_bitrate = min_bitrate self.audio_bitrate = audio_bitrate @@ -50,17 +51,25 @@ class AdaptiveHLS2YouTube: "-" ] try: - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print("[拉流] FFmpeg 启动成功") + + def read_stderr(): + while proc.poll() is None: + line = proc.stderr.readline() + if line: + print(f"[拉流FFmpeg]: {line.decode(errors='ignore').strip()}") + threading.Thread(target=read_stderr, daemon=True).start() + while not self.stop_flag.is_set(): - data = proc.stdout.read(188*2000) # 大块读取,减少空跑 + data = proc.stdout.read(188 * 5000) # 提升吞吐 if not data: time.sleep(0.05) continue try: - self.buffer_queue.put_nowait(data) # 非阻塞写入队列 + self.buffer_queue.put_nowait(data) except queue.Full: - continue # 队列满直接丢掉,保证不卡 + continue except Exception as e: print(f"拉流异常: {e}") @@ -79,6 +88,7 @@ class AdaptiveHLS2YouTube: "-c:v", "libx264", "-preset", "veryfast", "-tune", "zerolatency", + "-x264-params", "keyint=60:scenecut=0", "-b:v", f"{self.current_bitrate}k", "-maxrate", f"{self.current_bitrate}k", "-bufsize", f"{self.current_bitrate*4}k", @@ -89,6 +99,7 @@ class AdaptiveHLS2YouTube: "-b:a", f"{self.audio_bitrate}k", "-ar", "44100", "-ac", "2", + "-strict", "-2", "-f", "flv", "-rtmp_live", "live", f"rtmp://a.rtmp.youtube.com/live2/{youtube_key}" @@ -111,7 +122,8 @@ class AdaptiveHLS2YouTube: proc.stdin.write(data) proc.stdin.flush() except (BrokenPipeError, OSError): - break # 管道断开,退出推流循环 + print(f"[{room_name}] 推流管道断开,准备重启") + break except queue.Empty: continue except Exception as e: @@ -120,16 +132,16 @@ class AdaptiveHLS2YouTube: def _abr_thread(self): while not self.stop_flag.is_set(): queue_len = self.buffer_queue.qsize() - if queue_len > 100: - new_bitrate = max(self.min_bitrate, self.current_bitrate - 300) - elif queue_len < 30: - new_bitrate = min(self.max_bitrate, self.current_bitrate + 300) + if queue_len > 200: + new_bitrate = max(self.min_bitrate, self.current_bitrate - 500) + elif queue_len < 20: + new_bitrate = min(self.max_bitrate, self.current_bitrate + 500) else: new_bitrate = self.current_bitrate if new_bitrate != self.current_bitrate: print(f"[ABR] 调整码率: {self.current_bitrate}k -> {new_bitrate}k") self.current_bitrate = new_bitrate - time.sleep(max(self.check_interval, 10)) # 降低 ABR 更新频率,避免频繁干扰 + time.sleep(max(self.check_interval, 10)) def stop_all(self): print("停止所有推流...") @@ -173,19 +185,19 @@ def monitor_panel_thread(hls_instance, interval=2, max_width=50): while not hls_instance.stop_flag.is_set(): queue_len = hls_instance.buffer_queue.qsize() bitrate = hls_instance.current_bitrate - active_push = any(proc and proc.poll() is None for proc in hls_instance.processes.values()) + active_push = sum(1 for proc in hls_instance.processes.values() if proc and proc.poll() is None) queue_bar_len = min(bar_width, queue_len) queue_bar = "#" * queue_bar_len + "-" * (bar_width - queue_bar_len) print("\r", end="") - print(f"[监控] 队列: [{queue_bar}] {queue_len:4} | 码率: {bitrate:4}k | 推流活跃: {active_push}", end="") + print(f"[监控] 队列: [{queue_bar}] {queue_len:4} | 码率: {bitrate:4}k | 推流进程: {active_push}", end="") time.sleep(interval) # ----------------- 示例 ----------------- if __name__ == "__main__": - DOUYIN_URL = "https://live.douyin.com/8687122573" + DOUYIN_URL = "https://live.douyin.com/89581874559" YOUTUBE_KEY = "qxvb-r47b-r5ju-6ud3-6k7z" hls_instance = start_douyin_to_youtube(DOUYIN_URL, YOUTUBE_KEY, delay_sec=40)