| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- import os
- import subprocess
- import time
- import re
- from setting import RTMP_URL, CAM_NAME, AUDIO_DEVICE, FONT_PATH
- # --- 配置参数 ---
- # 替换为你的 ffmpeg 命令(建议先在终端测试成功)
- FFMPEG_CMD = [
- 'ffmpeg',
- '-hide_banner',
- '-thread_queue_size', '2048',
- '-f', 'video4linux2',
- '-video_size', '1024x768',
- '-framerate', '25',
- '-i', '/dev/video0',
- '-thread_queue_size', '8192',
- '-f', 'alsa',
- '-ac', '1',
- '-i', AUDIO_DEVICE,
- '-vcodec', 'libx264',
- '-acodec', 'aac',
- '-b:v', '4M',
- '-b:a', '128K',
- '-max_delay', '1000000',
- '-g', '50',
- '-preset:v', 'ultrafast',
- '-tune:v', 'zerolatency',
- '-vf', (
- f"drawtext=fontfile={FONT_PATH}:"
- f"text='{CAM_NAME} | %{{localtime\\:%Y-%m-%d %H\\\\\\:%M\\\\\\:%S}}':"
- "x=20:y=20:fontsize=28:fontcolor=yellow:shadowcolor=black:shadowx=2:shadowy=2"
- ),
- '-f', 'flv',
- RTMP_URL
- ]
- RESTART_DELAY = 5 # 重启间隔(秒)
- def monitor_stream():
- while True:
- # 杀死所有属于当前用户的 ffmpeg 进程,防止冲突
- os.system("pkill -9 ffmpeg > /dev/null 2>&1")
- print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 正在启动 FFmpeg 推流...")
- # 启动进程,将 stderr 重定向以便监控状态
- process = subprocess.Popen(
- FFMPEG_CMD,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- universal_newlines=True,
- bufsize=1
- )
- try:
- # 实时读取 FFmpeg 输出的状态行
- while True:
- line = process.stdout.readline()
- if not line:
- break
- # 监控推流状态(例如抓取 fps 和 bitrate)
- if "frame=" in line:
- # 使用正则或字符串切片提取关键信息
- stats = re.findall(r'(frame=.*?bitrate=.*?speed=.*?x)', line)
- if stats:
- print(f"\r推流中: {stats[0].strip()}", end="")
- else:
- print(f"\n[FFmpeg 日志] {line.strip()}")
- # 检查进程是否意外退出
- if process.poll() is not None:
- break
- except Exception as e:
- print(f"\n监控异常: {e}")
- finally:
- # 确保彻底杀死进程
- if process.poll() is None:
- process.terminate()
- try:
- process.wait(timeout=5)
- except subprocess.TimeoutExpired:
- process.kill()
- print(f"[{time.strftime('%H:%M:%S')}] FFmpeg 进程已结束,{RESTART_DELAY}秒后重启...")
- time.sleep(RESTART_DELAY)
- if __name__ == "__main__":
- try:
- monitor_stream()
- except KeyboardInterrupt:
- print("用户手动停止,程序退出。")
|