智慧园区多摄像头批量部署脚本(一键启动/停止/监控)

本次提供的批量部署脚本适配园区多摄像头集群场景,支持一键启动所有摄像头录制进程、一键停止批量运维、实时监控进程状态,解决单摄像头脚本逐个操作的低效问题,大幅提升大规模部署与运维效率。

一、 前置准备:摄像头配置清单

1. 创建摄像头配置文件

首先在 /data/park/scripts 目录下创建 camera_list.conf 配置文件,集中管理所有摄像头信息,格式为「摄像头ID|RTSP地址|保存目录」(竖线分隔,一行一个摄像头)。

# 摄像头配置清单(格式:CAMERA_ID|RTSP_URL|SAVE_DIR)
cam001|rtsp://admin:123456@192.168.1.100:554/stream1|/data/park/record/cam001
cam002|rtsp://admin:123456@192.168.1.101:554/stream1|/data/park/record/cam002
cam003|rtsp://admin:123456@192.168.1.102:554/stream1|/data/park/record/cam003
# 可按需追加更多摄像头(支持几十上百台集群)

2. 配置说明

  • 每一行对应一台摄像头,不可有空行或格式错误
  • 保存目录自动创建,无需手动提前建立
  • 建议摄像头ID与物理点位对应(如 cam_gate01 大门1号摄像头),便于检索

二、 核心批量部署脚本(camera_batch_manage.sh

功能说明

  1. 支持 3 种核心操作:start(一键启动所有摄像头录制)、stop(一键停止所有录制进程)、status(实时监控所有进程状态)
  2. 自动读取 camera_list.conf 配置,无需修改脚本核心逻辑
  3. 保留单摄像头脚本的「故障自动重启」「分段录制」「日志记录」功能
  4. 批量启动时自动创建各摄像头的录像目录和日志目录
  5. 批量停止时安全终止进程,避免录像文件损坏
  6. 状态监控时清晰展示各摄像头「运行中/已停止」状态,便于快速排查离线设备

完整脚本代码

#!/bin/bash
# 智慧园区多摄像头批量管理脚本(一键启动/停止/监控)
# 核心配置
CONF_FILE="/data/park/scripts/camera_list.conf"  # 摄像头配置文件路径
SCRIPT_DIR="/data/park/scripts"  # 脚本目录
LOG_ROOT="/data/park/logs"  # 全局日志根目录
SEGMENT_TIME=3600  # 每段录像时长(秒),1小时=3600秒
RESTART_INTERVAL=10  # 单摄像头异常重启间隔(秒)

# 步骤1:检查配置文件是否存在
if [ ! -f ${CONF_FILE} ]; then
    echo "【错误】摄像头配置文件不存在:${CONF_FILE}"
    exit 1
fi

# 步骤2:定义单摄像头录制核心函数(与单脚本功能一致)
single_camera_record() {
    local CAMERA_ID=$1
    local RTSP_URL=$2
    local SAVE_DIR=$3
    local LOG_FILE="${LOG_ROOT}/${CAMERA_ID}_record.log"

    # 创建录像目录和日志目录
    mkdir -p ${SAVE_DIR}
    mkdir -p ${LOG_ROOT}

    # 写入启动日志
    echo "=====================================" >> ${LOG_FILE}
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 摄像头${CAMERA_ID}录制进程启动(批量部署)" >> ${LOG_FILE}
    echo "RTSP地址:${RTSP_URL}" >> ${LOG_FILE}
    echo "录像保存目录:${SAVE_DIR}" >> ${LOG_FILE}
    echo "每段时长:${SEGMENT_TIME}秒,重启间隔:${RESTART_INTERVAL}秒" >> ${LOG_FILE}

    # 无限循环 + 故障自动重启
    while true; do
        ffmpeg -y \
        -rtsp_transport tcp \
        -i ${RTSP_URL} \
        -c copy \
        -f segment \
        -segment_time ${SEGMENT_TIME} \
        -segment_format mp4 \
        -segment_filename "${SAVE_DIR}/${CAMERA_ID}_%Y%m%d_%H%M%S.mp4" \
        -v error \
        >> ${LOG_FILE} 2>&1

        # 异常退出记录日志
        local exit_code=$?
        echo "$(date +'%Y-%m-%d %H:%M:%S') - 摄像头${CAMERA_ID}录制进程异常退出(退出码:${exit_code})" >> ${LOG_FILE}
        echo "$(date +'%Y-%m-%d %H:%M:%S') - ${RESTART_INTERVAL}秒后自动重启..." >> ${LOG_FILE}
        sleep ${RESTART_INTERVAL}
    done
}

# 步骤3:一键启动所有摄像头(start 命令)
batch_start() {
    echo "【开始】批量启动所有摄像头录制进程..."
    echo "读取配置文件:${CONF_FILE},共 $(wc -l < ${CONF_FILE}) 台摄像头"

    # 遍历配置文件,启动每台摄像头
    while IFS="|" read -r CAMERA_ID RTSP_URL SAVE_DIR; do
        # 跳过空行和注释行
        if [[ -z ${CAMERA_ID} || ${CAMERA_ID:0:1} == "#" ]]; then
            continue
        fi

        # 检查进程是否已运行,避免重复启动
        if ps -ef | grep -v grep | grep -q "single_camera_record ${CAMERA_ID}"; then
            echo "【跳过】摄像头${CAMERA_ID}进程已运行,无需重复启动"
            continue
        fi

        # 后台启动录制进程(nohup 确保后台运行)
        echo "【启动】摄像头${CAMERA_ID}(RTSP:${RTSP_URL})"
        nohup bash -c "single_camera_record ${CAMERA_ID} '${RTSP_URL}' ${SAVE_DIR}" > /dev/null 2>&1 &

        # 短暂延迟,避免服务器压力过大
        sleep 1
    done < ${CONF_FILE}

    echo "【完成】所有摄像头录制进程启动指令已下发,可执行 ./camera_batch_manage.sh status 查看状态"
}

# 步骤4:一键停止所有摄像头(stop 命令)
batch_stop() {
    echo "【开始】批量停止所有摄像头录制进程..."

    # 遍历配置文件,停止每台摄像头进程
    while IFS="|" read -r CAMERA_ID RTSP_URL SAVE_DIR; do
        # 跳过空行和注释行
        if [[ -z ${CAMERA_ID} || ${CAMERA_ID:0:1} == "#" ]]; then
            continue
        fi

        # 查找并安全终止进程
        local pid=$(ps -ef | grep -v grep | grep "single_camera_record ${CAMERA_ID}" | awk '{print $2}')
        if [ -n "${pid}" ]; then
            echo "【停止】摄像头${CAMERA_ID}(进程ID:${pid})"
            kill -9 ${pid} > /dev/null 2>&1
            # 删除进程残留标记
            rm -f /tmp/${CAMERA_ID}_alert.flag > /dev/null 2>&1
        else
            echo "【跳过】摄像头${CAMERA_ID}进程未运行,无需停止"
        fi
    done < ${CONF_FILE}

    echo "【完成】所有摄像头录制进程已停止"
}

# 步骤5:监控所有摄像头状态(status 命令)
batch_status() {
    echo "====================================="
    echo "$(date +'%Y-%m-%d %H:%M:%S') - 园区摄像头录制进程状态监控"
    echo "====================================="
    echo "摄像头ID       | 进程状态 | 录像目录"
    echo "-------------------------------------"

    # 遍历配置文件,查询每台摄像头状态
    while IFS="|" read -r CAMERA_ID RTSP_URL SAVE_DIR; do
        # 跳过空行和注释行
        if [[ -z ${CAMERA_ID} || ${CAMERA_ID:0:1} == "#" ]]; then
            continue
        fi

        # 判断进程状态
        if ps -ef | grep -v grep | grep -q "single_camera_record ${CAMERA_ID}"; then
            STATUS="运行中"
        else
            STATUS="已停止"
        fi

        # 格式化输出(对齐展示,更清晰)
        printf "%-15s | %-6s | %s\n" ${CAMERA_ID} ${STATUS} ${SAVE_DIR}
    done < ${CONF_FILE}

    echo "====================================="
    echo "状态说明:运行中=正常录制,已停止=需排查摄像头/网络/进程"
}

# 步骤6:命令行参数判断(入口逻辑)
if [ $# -ne 1 ]; then
    echo "【使用说明】本脚本支持 3 种操作:"
    echo "  1. 一键启动所有摄像头:./camera_batch_manage.sh start"
    echo "  2. 一键停止所有摄像头:./camera_batch_manage.sh stop"
    echo "  3. 监控所有摄像头状态:./camera_batch_manage.sh status"
    exit 1
fi

case $1 in
    "start")
        batch_start
        ;;
    "stop")
        batch_stop
        ;;
    "status")
        batch_status
        ;;
    *)
        echo "【错误】不支持的命令,请使用 start/stop/status"
        exit 1
        ;;
esac

exit 0

三、 脚本使用步骤

1. 部署与权限配置

  1. 将脚本保存至 /data/park/scripts 目录
  2. 赋予执行权限:
    chmod +x /data/park/scripts/camera_batch_manage.sh
    
  3. 确保 camera_list.conf 配置正确,与脚本在同一目录

2. 核心操作命令

(1) 一键启动所有摄像头
cd /data/park/scripts
./camera_batch_manage.sh start
  • 执行后会逐一下发启动指令,自动创建各摄像头的录像/日志目录
  • 后台运行,终端关闭不影响进程
  • 启动完成后可通过 status 命令验证状态
(2) 一键停止所有摄像头
./camera_batch_manage.sh stop
  • 安全终止所有录制进程,避免录像文件损坏
  • 适合园区设备维护、服务器重启前的准备工作
  • 停止后所有摄像头不再生成新录像文件
(3) 实时监控所有摄像头状态
./camera_batch_manage.sh status
  • 清晰展示每台摄像头的「进程状态」和「录像目录」
  • 快速定位「已停止」的摄像头,便于排查 RTSP 地址错误、摄像头离线、网络故障等问题
  • 示例输出效果:
    =====================================
    2026-01-12 15:30:00 - 园区摄像头录制进程状态监控
    =====================================
    摄像头ID       | 进程状态 | 录像目录
    -------------------------------------
    cam001          | 运行中   | /data/park/record/cam001
    cam002          | 运行中   | /data/park/record/cam002
    cam003          | 已停止   | /data/park/record/cam003
    =====================================
    状态说明:运行中=正常录制,已停止=需排查摄像头/网络/进程
    

3. 日志查看

各摄像头的录制日志独立保存,便于单独排查故障:

# 查看 cam001 摄像头录制日志
tail -f /data/park/logs/cam001_record.log

# 查看 cam003 摄像头异常日志(已停止状态)
grep "异常退出" /data/park/logs/cam003_record.log

四、 大规模部署优化注意事项

  1. 服务器资源规划
    • 每台摄像头录制会占用一定 CPU/内存/网络带宽,建议按「每 100 台摄像头」配置 8 核 16G 以上服务器
    • 存储采用 RAID 阵列或分布式存储,避免单盘故障导致录像丢失
  2. 配置文件备份
    • camera_list.conf 备份至远程服务器,避免配置丢失导致批量部署失败
    • 新增/删除摄像头后,及时更新配置文件并备份
  3. 避免启动风暴
    • 脚本内置 1 秒启动延迟,避免几十上百台摄像头同时启动占用大量服务器资源
    • 若摄像头数量超过 200 台,可修改 sleep 1sleep 2,进一步降低启动压力
  4. 进程监控补充
    • 可配合 zabbix/prometheus 监控脚本进程,实现「进程停止自动告警」
    • 定期执行 ./camera_batch_manage.sh status,并将结果写入监控系统,形成闭环
  5. 录像目录清理
    • 批量压缩脚本可读取 camera_list.conf 配置,实现所有摄像头历史录像的统一压缩
    • 新增定时任务,定期清理所有摄像头超过保留期限的录像文件:
      # 每天凌晨 1 点清理 30 天前的录像
      0 1 * * * find /data/park/record -name "*.mp4" -mtime +30 -delete
      

五、 常见问题排查

  1. 部分摄像头启动失败
    • 排查配置文件中该摄像头的 RTSP 地址是否正确
    • 手动测试 RTSP 连通性:ffmpeg -i rtsp://xxx
    • 查看对应摄像头日志:tail -f /data/park/logs/xxx_record.log
  2. 批量启动后状态显示「已停止」
    • 检查服务器是否有足够磁盘空间
    • 检查摄像头是否在线,园区网络是否通畅
    • 检查脚本执行权限是否足够
  3. 停止后无法重新启动
    • 排查是否有残留进程:ps -ef | grep single_camera_record
    • 手动删除残留进程后重新启动:kill -9 残留进程ID

至此,智慧园区 FFmpeg 自动化运维体系已实现从单摄像头到多摄像头集群的完整落地,涵盖「批量部署→自动录制→故障重启→批量运维→监控告警→存储管理」全流程。

Logo

音视频技术社区,一个全球开发者共同探讨、分享、学习音视频技术的平台,加入我们,与全球开发者一起创造更加优秀的音视频产品!

更多推荐