You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重启出错的FFmpeg RTSP转RTMP进程并解决无法终止问题

解决FFmpeg RTSP转RTMP自动重启脚本无法终止的问题

问题分析

原脚本的while true; do $cmd && break; done逻辑会在FFmpeg进程退出(无论正常还是异常)时立刻重启,且未处理终止信号:

  • 如果仅杀死FFmpeg子进程,父脚本会检测到执行失败,立即启动新的FFmpeg进程,导致“无法终止”的假象
  • 若直接杀死脚本进程,kill -9虽然能强制终止,但脚本没有机会清理子进程,可能残留FFmpeg进程

改进后的脚本

使用信号捕获机制,让脚本能够响应终止指令,同时清理子进程:

#!/bin/bash

# 定义终止信号处理函数
cleanup() {
    echo "收到终止信号,正在停止FFmpeg进程..."
    if [ -n "$FFMPEG_PID" ]; then
        kill -9 "$FFMPEG_PID" 2>/dev/null
        wait "$FFMPEG_PID" 2>/dev/null
    fi
    exit 0
}

# 捕获SIGINT(Ctrl+C)和SIGTERM(kill命令)信号
trap cleanup SIGINT SIGTERM

# 检查参数是否齐全
if [ $# -ne 2 ]; then
    echo "用法: $0 <RTSP源地址> <RTMP推流地址>"
    exit 1
fi

# 循环执行FFmpeg,直到正常退出或收到终止信号
while true; do
    # 启动FFmpeg并后台运行,记录PID
    ffmpeg -re -rtsp_transport tcp -i "$1" -c:v copy -c:a aac -ar 44100 -ac 1 -f flv -flvflags no_duration_filesize "$2" &
    FFMPEG_PID=$!
    # 等待FFmpeg进程结束,获取退出码
    wait "$FFMPEG_PID"
    EXIT_CODE=$?
    # 如果是正常退出(码0),则终止循环
    if [ $EXIT_CODE -eq 0 ]; then
        echo "FFmpeg正常退出,结束脚本"
        break
    fi
    # 异常退出则打印日志并重启
    echo "FFmpeg异常退出(码$EXIT_CODE),10秒后重启..."
    sleep 10
done

关键改进点

  • 信号捕获:通过trap命令监听SIGINT和SIGTERM信号,收到信号时调用cleanup函数杀死FFmpeg子进程并退出脚本
  • 进程管理:记录FFmpeg的PID,确保终止时能清理子进程
  • 参数安全:直接使用位置参数$1、$2并加引号,避免参数含空格时解析错误
  • 退出码判断:仅当FFmpeg正常退出(退出码0)时才终止循环,异常退出自动重启
  • 延迟重启:添加sleep 10避免频繁重启导致资源占用过高

正确终止方法

  1. 前台运行时:直接按Ctrl+C,脚本会自动清理FFmpeg进程并退出
  2. 后台运行时:
    • 先找到脚本的PID:ps aux | grep 脚本名.sh | grep -v grep
    • 发送终止信号:kill <脚本PID>(推荐)或kill -9 <脚本PID>(强制终止)

额外建议

  • 可以添加日志输出到文件,方便排查FFmpeg异常退出原因:在FFmpeg命令后追加>> /var/log/ffmpeg_rtsp2rtmp.log 2>&1
  • 若FFmpeg频繁异常退出,建议先排查RTSP源稳定性或推流地址的网络问题,从根源解决重启需求

内容的提问来源于stack exchange,提问作者Samsul Islam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:15:27