's'
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
cache/
|
cache/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
records/
|
||||||
|
|||||||
15
backup/back7
15
backup/back7
@@ -7,6 +7,7 @@ import time
|
|||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
import platform
|
||||||
import spider
|
import spider
|
||||||
import stream
|
import stream
|
||||||
|
|
||||||
@@ -17,6 +18,8 @@ logging.basicConfig(
|
|||||||
datefmt="%H:%M:%S"
|
datefmt="%H:%M:%S"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IS_WINDOWS = platform.system() == "Windows"
|
||||||
|
|
||||||
# ----------------- Douyin to YouTube Streamer -----------------
|
# ----------------- Douyin to YouTube Streamer -----------------
|
||||||
class DouyinToYouTubeStreamer:
|
class DouyinToYouTubeStreamer:
|
||||||
def __init__(self, bitrate=5000, audio_bitrate=128, resolution='720x1280',
|
def __init__(self, bitrate=5000, audio_bitrate=128, resolution='720x1280',
|
||||||
@@ -87,7 +90,7 @@ class DouyinToYouTubeStreamer:
|
|||||||
'-b:a', f'{self.audio_bitrate}k',
|
'-b:a', f'{self.audio_bitrate}k',
|
||||||
'-ar', '44100',
|
'-ar', '44100',
|
||||||
'-ac', '2',
|
'-ac', '2',
|
||||||
'-movflags', '+faststart+frag_keyframe', # <--- 关键修改
|
'-movflags', '+faststart+frag_keyframe',
|
||||||
self.out_file
|
self.out_file
|
||||||
]
|
]
|
||||||
return cmd
|
return cmd
|
||||||
@@ -181,10 +184,14 @@ class DouyinToYouTubeStreamer:
|
|||||||
def _finalize_recording(self):
|
def _finalize_recording(self):
|
||||||
if self.out_file and os.path.exists(self.out_file):
|
if self.out_file and os.path.exists(self.out_file):
|
||||||
try:
|
try:
|
||||||
# 如果进程未退出,先发送中断信号完成封装
|
# 根据系统发送信号完成封装
|
||||||
if self.record_proc and self.record_proc.poll() is None:
|
if self.record_proc and self.record_proc.poll() is None:
|
||||||
self.record_proc.send_signal(signal.CTRL_BREAK_EVENT if os.name == 'nt' else signal.SIGINT)
|
sig = signal.CTRL_BREAK_EVENT if IS_WINDOWS else signal.SIGINT
|
||||||
|
self.record_proc.send_signal(sig)
|
||||||
|
try:
|
||||||
self.record_proc.wait(timeout=5)
|
self.record_proc.wait(timeout=5)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
self.record_proc.kill()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -197,7 +204,6 @@ class DouyinToYouTubeStreamer:
|
|||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
new_name = self.out_file.replace(".mp4", f"_{uuid.uuid4().hex[:4]}.mp4")
|
new_name = self.out_file.replace(".mp4", f"_{uuid.uuid4().hex[:4]}.mp4")
|
||||||
os.rename(self.out_file, new_name)
|
os.rename(self.out_file, new_name)
|
||||||
|
|
||||||
size_mb = os.path.getsize(new_name) / (1024 * 1024)
|
size_mb = os.path.getsize(new_name) / (1024 * 1024)
|
||||||
logging.info(f"[{self.room_name}] 本地录制已结束: {new_name} | 大小: {size_mb:.2f} MB")
|
logging.info(f"[{self.room_name}] 本地录制已结束: {new_name} | 大小: {size_mb:.2f} MB")
|
||||||
|
|
||||||
@@ -246,5 +252,6 @@ if __name__ == "__main__":
|
|||||||
signal.signal(signal.SIGTERM, signal_handler)
|
signal.signal(signal.SIGTERM, signal_handler)
|
||||||
|
|
||||||
logging.info("程序已启动,低延迟推流中,按 Ctrl+C 停止...")
|
logging.info("程序已启动,低延迟推流中,按 Ctrl+C 停止...")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
time.sleep(60)
|
time.sleep(60)
|
||||||
|
|||||||
14
live.py
14
live.py
@@ -7,6 +7,7 @@ import time
|
|||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
import platform
|
||||||
import spider
|
import spider
|
||||||
import stream
|
import stream
|
||||||
|
|
||||||
@@ -17,6 +18,8 @@ logging.basicConfig(
|
|||||||
datefmt="%H:%M:%S"
|
datefmt="%H:%M:%S"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IS_WINDOWS = platform.system() == "Windows"
|
||||||
|
|
||||||
# ----------------- Douyin to YouTube Streamer -----------------
|
# ----------------- Douyin to YouTube Streamer -----------------
|
||||||
class DouyinToYouTubeStreamer:
|
class DouyinToYouTubeStreamer:
|
||||||
def __init__(self, bitrate=5000, audio_bitrate=128, resolution='720x1280',
|
def __init__(self, bitrate=5000, audio_bitrate=128, resolution='720x1280',
|
||||||
@@ -87,7 +90,7 @@ class DouyinToYouTubeStreamer:
|
|||||||
'-b:a', f'{self.audio_bitrate}k',
|
'-b:a', f'{self.audio_bitrate}k',
|
||||||
'-ar', '44100',
|
'-ar', '44100',
|
||||||
'-ac', '2',
|
'-ac', '2',
|
||||||
'-movflags', '+faststart+frag_keyframe', # <--- 关键修改
|
'-movflags', '+faststart+frag_keyframe',
|
||||||
self.out_file
|
self.out_file
|
||||||
]
|
]
|
||||||
return cmd
|
return cmd
|
||||||
@@ -181,10 +184,14 @@ class DouyinToYouTubeStreamer:
|
|||||||
def _finalize_recording(self):
|
def _finalize_recording(self):
|
||||||
if self.out_file and os.path.exists(self.out_file):
|
if self.out_file and os.path.exists(self.out_file):
|
||||||
try:
|
try:
|
||||||
# 如果进程未退出,先发送中断信号完成封装
|
# 根据系统发送信号完成封装
|
||||||
if self.record_proc and self.record_proc.poll() is None:
|
if self.record_proc and self.record_proc.poll() is None:
|
||||||
self.record_proc.send_signal(signal.CTRL_BREAK_EVENT if os.name == 'nt' else signal.SIGINT)
|
sig = signal.CTRL_BREAK_EVENT if IS_WINDOWS else signal.SIGINT
|
||||||
|
self.record_proc.send_signal(sig)
|
||||||
|
try:
|
||||||
self.record_proc.wait(timeout=5)
|
self.record_proc.wait(timeout=5)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
self.record_proc.kill()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -197,7 +204,6 @@ class DouyinToYouTubeStreamer:
|
|||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
new_name = self.out_file.replace(".mp4", f"_{uuid.uuid4().hex[:4]}.mp4")
|
new_name = self.out_file.replace(".mp4", f"_{uuid.uuid4().hex[:4]}.mp4")
|
||||||
os.rename(self.out_file, new_name)
|
os.rename(self.out_file, new_name)
|
||||||
|
|
||||||
size_mb = os.path.getsize(new_name) / (1024 * 1024)
|
size_mb = os.path.getsize(new_name) / (1024 * 1024)
|
||||||
logging.info(f"[{self.room_name}] 本地录制已结束: {new_name} | 大小: {size_mb:.2f} MB")
|
logging.info(f"[{self.room_name}] 本地录制已结束: {new_name} | 大小: {size_mb:.2f} MB")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user