Files
gitlab-instance-0a899031_dy…/livee.py
2025-09-13 08:13:47 +08:00

103 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import subprocess
import threading
import time
import glob
import asyncio
import uuid
import spider
import stream
class Douyin2YouTube:
def __init__(self, cache_dir="cache", segment_time=10):
self.cache_dir = cache_dir
self.segment_time = segment_time
os.makedirs(cache_dir, exist_ok=True)
async def get_real_url(self, record_url, record_quality="原画"):
# 调用你的抖音爬虫模块获取真实直播流
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)
else:
json_data = await spider.get_douyin_app_stream_data(url=record_url)
port_info = await stream.get_douyin_stream_url(json_data, record_quality, None)
return port_info.get("record_url")
def start(self, record_url, youtube_key, room_name=None):
room_name = room_name or f"抖音_{str(uuid.uuid4())[:8]}"
real_url = asyncio.run(self.get_real_url(record_url))
if not real_url:
print(f"[{room_name}] 获取真实直播流失败")
return
print(f"[{room_name}] 实际直播流: {real_url}")
tmp_prefix = os.path.join(self.cache_dir, f"{room_name}_")
for f in glob.glob(f"{tmp_prefix}*.ts"):
os.remove(f)
# ----------------- 拉流线程 -----------------
def record_thread():
while True:
cmd = [
"ffmpeg",
"-user_agent", "Mozilla/5.0",
"-headers", "Referer: https://www.douyin.com/",
"-rw_timeout", "15000000",
"-fflags", "+genpts+igndts+nobuffer",
"-flags", "low_delay",
"-reconnect", "1",
"-reconnect_streamed", "1",
"-reconnect_delay_max", "10",
"-i", real_url,
"-c", "copy",
"-f", "segment",
"-segment_time", str(self.segment_time),
"-reset_timestamps", "1",
f"{tmp_prefix}%03d.ts"
]
try:
subprocess.run(cmd)
except Exception as e:
print(f"[{room_name}] 拉流异常: {e}, 10秒后重试")
time.sleep(10)
# ----------------- 推流线程 -----------------
def push_thread():
pushed_files = set()
while True:
segments = sorted(glob.glob(f"{tmp_prefix}*.ts"))
new_segments = [s for s in segments if s not in pushed_files]
for seg in new_segments:
cmd = [
"ffmpeg",
"-re",
"-i", seg,
"-c:v", "libx264", "-preset", "veryfast",
"-b:v", "3000k", "-maxrate", "3000k", "-bufsize", "6000k",
"-r", "30", "-g", "60",
"-c:a", "aac", "-b:a", "128k",
"-f", "flv",
f"rtmp://a.rtmp.youtube.com/live2/{youtube_key}"
]
try:
subprocess.run(cmd)
pushed_files.add(seg)
except Exception as e:
print(f"[{room_name}] 推流异常: {e}, 10秒后重试")
time.sleep(10)
time.sleep(1)
threading.Thread(target=record_thread, daemon=True).start()
threading.Thread(target=push_thread, daemon=True).start()
print(f"[{room_name}] 转播线程已启动YouTube 推流保证连续")
# ----------------- 示例 -----------------
if __name__ == "__main__":
DOUYIN_URL = "https://live.douyin.com/210443559964" # 填抖音直播 URL
YOUTUBE_KEY = "qxvb-r47b-r5ju-6ud3-6k7z" # 填 YouTube 直播 Key
broadcaster = Douyin2YouTube()
broadcaster.start(DOUYIN_URL, YOUTUBE_KEY)
while True:
time.sleep(60)