有一个 ffmpeg 实例在 VPS 上作为服务器运行,它将 RTSP 视频转换为 HLS 并将其提供给网络(使用 Apache)。RTSP 视频来自其他地方的计算机(在本例中是另一个城镇),我有一个 IP 摄像头连接到该计算机。计算机从 IP 摄像头获取 RTSP 数据并将其重新转换到 VPS。
这是我在那台计算机(我可以说是重新流式传输器)上使用的 ffmpeg 命令:
ffmpeg \
-rtsp_transport tcp \
-i rtsp://[IP address of the camera]:554/live \
-c:v copy \
-f rtsp \
-rtsp_transport tcp \
rtsp://[IP address of the VPS]:4445/live.sdp
这是我在 VPS 上使用的命令:
ffmpeg \
-rtsp_flags listen \
-listen_timeout 5 \
-timeout 5000000 \
-rtsp_transport tcp \
-i rtsp://[ip address of the VPS]:4445/live.sdp \
-map 0 \
-flags +global_header \
-fflags +igndts \
-c:v copy \
-g 0 \
-b:v 125k \
-maxrate 250k \
-bufsize 500k \
-hls_time 1 \
-hls_list_size 15 \
-hls_wrap 15 \
-y /dev/shm/hls/video.m3u8
到目前为止,一切都运行良好:我可以在浏览器中读取 HLS 流,而且它非常稳定和快速。当重新流化器和 VPS 之间的连接断开时,问题就出现了:我必须通过 ssh 进入 VPS 并手动重新启动 ffmpeg 实例。当地址-i
(在 VPS 端)没有输入时,是否可以告诉 ffmpeg“崩溃”(或只是停止其进程)?我正在使用一个可以自动重新启动进程的 bash 脚本,所以这已经解决了。
为了避免混淆:根据ffmpeg 的官方文档该timeout
标志以 MICROSECONDS 作为值,并listen_timeout
以 SECONDS 为单位。我见过很多人在争论这个话题 :)
答案1
希望我没有迟到。我通过监控 CPU 使用率解决了类似的问题。在我的例子中,当摄像机重新启动或连接断开时,FFMPEG 继续运行,但 CPU 使用率降至 0.0%。我使用 python 来监控它。以下是重要部分:
import subprocess, psutil
import time, os
# Run ffmpeg command
base_process = subprocess.Popen([
'ffmpeg',
'-rtsp_transport', 'tcp',
'-i', LINK_RTSP,
'-map', '0:v', '-map', '0:a', '-vcodec', 'copy', '-acodec', 'aac', '-t', 60,
os.path.expanduser(f'~/Desktop/{date}.mp4')
])
#Check process by CPU usage
control_process = psutil.Process(base_process.pid)
attempts = 5 #Sleep is 1 second, so if ffmpeg is not using cpu for 5 seconds, kill the process
while base_process.poll() is None:
cpu_percent = control_process.cpu_percent()
if cpu_percent == 0.0:
attempts -= 1
if attempts == 0:
logger.info("ffmpeg is hanging (CPU usage is 0%). Killing the process!")
while base_process.poll() is None:
base_process.terminate()
time.sleep(1)
logger.info(f"Files to be recoved: {date}.mp4")
try:
for camera in connected_cameras.keys():
os.rename(os.path.expanduser(f'{BASE_FOLDER}{camera}/{date}.mp4'), os.path.expanduser(f'{BASE_FOLDER}{camera}/{date}_recovery-needed.mp4'))
except:
pass
break
time.sleep(1)
我希望它有帮助。