从零搭建RTSP视频流测试环境:手把手教学(FFmpeg方案)

从零搭建RTSP视频流测试环境:手把手教学(FFmpeg方案)

引言

在视频分析系统的开发与测试中,真实可靠的视频流获取常常是影响效率的关键一环。开发者往往面临几类典型难题:真实摄像头设备采购周期长、异常场景难以复现;公共 RTSP 流易受网络限制,且分辨率、帧率难以适配;商业流媒体服务则成本高昂,不便于快速验证与调试。

为应对这些痛点,本文介绍一种基于开源工具快速搭建本地 RTSP 视频流的轻量化方案。该方法使用 rtsp-simple-server 作为流媒体服务器,并结合 FFmpeg 将本地视频文件转为 RTSP 流,既降低了成本与依赖,也提高了测试环境的可控性与灵活性。

一、准备工作

1.1 演示环境

工具 版本 描述
操作系统 Linux CentOS 7 操作系统
rtsp-simple-server v0.21.6 轻量级RTSP服务器
FFmpeg 4.1 多媒体处理工具
Python 3.x 可选,用于自动化脚本

1.2 文件准备

测试视频文件(如test.mp4,建议1080P以内)

二、安装核心工具

2.1 部署rtsp-simple-server

# 从 GitHub 上下载 rtsp-simple-server
wget https://github.com/bluenviron/mediamtx/releases/download/v0.21.6/rtsp-simple-server_v0.21.6_linux_amd64.tar.gz

# 解压
tar -xzf rtsp-simple-server_v0.21.6_linux_amd64.tar.gz

# 运行 rtsp-simple-server 服务
./rtsp-simple-server

image

从 GitHub 下载巨慢,可以通过我分享的阿里云盘链接进行下载:rtsp-simple-server_v0.21.6_linux_amd64.rar

由于我将压缩包已经再次压缩,需要先解压后,再上传至服务器,再执行以上命令

2.2 安装FFmpeg

# 下载 FFmpeg
wget https://ffmpeg.org/releases/ffmpeg-4.1.tar.xz

# 解压 FFmpeg
tar xvJf ffmpeg-4.1.tar.xz

cd ffmpeg-4.1

# 安装 gcc 编译器(因为我的 gcc 的版本为 4.8.5, 所以 ffmpeg 只能使用低版本)
yum install gcc

yasm 软件包不在 CentOS 7 默认的 yum 仓库中,所以需要提前启用EPEL仓库

# 安装EPEL仓库
yum install epel-release

# 更新yum缓存
yum makecache

#安装 yasm 编译器
yum install yasm

进行FFmpeg 源码编译, /usr/local/ffmpeg 为自己指定的安装目录

./configure --enable-shared --prefix=/usr/local/ffmpeg

执行 make, 要等很久很久......

make

执行过程中存在警告是不影响使用的

image

执行安装

make install

修改文件 /etc/ld.so.conf

vim /etc/ld.so.conf

输入以下内容

include ld.so.conf.d/*.conf
/usr/local/ffmpeg/lib/

执行 ldconfig 使修改生效

ldconfig

验证 ffmpeg 是否安装成功

/usr/local/ffmpeg/bin/ffmpeg -version

image

配置环境变量

vim /etc/profile

在最后PATH添加环境变量:

#set ffmpeg environment
PATH=$PATH:/usr/local/ffmpeg/bin
export PATH

使环境变量生效

source /etc/profile

验证环境变量是否配置成功

ffmpeg -version

image

三、使用FFmpeg推送视频流

3.1 基础命令

将本地MP4转为RTSP流:

ffmpeg \
  -y \
  -i test.mp4 \
  -f rawvideo \
  -vcodec rawvideo \
  -pix_fmt bgr24 \
  -c:v mpeg1video \
  -b:v 1000k \
  -f rtsp \
  rtsp://localhost:8554/live

命令解析:

ffmpeg \
  -y \                       # 自动覆盖输出文件
  -i test.mp4 \              # 输出MP4视频
  -f rawvideo \              # 输入格式:原始视频
  -vcodec rawvideo \         # 输入编码:原始视频
  -pix_fmt bgr24 \           # 像素格式:BGR 24位(OpenCV 默认)
  -c:v mpeg1video \          # 视频编码器:MPEG-1
  -b:v 1000k \               # 视频码率:1000 kbps
  -f rtsp \                  # 输出格式:RTSP 流
  rtsp://localhost:8554/live # RTSP 输出地址

3.2 Python自动化脚本

pip 安装 numpy opencv-python

python3 -m pip install "numpy<2.0" opencv-python

创建stream_publisher.py

import cv2
import subprocess
import signal
import sys


def push_file_to_rtsp(input_file, rtsp_url):
    """
    将本地视频文件推流到RTSP服务器

    Args:
        input_file: 输入视频文件路径
        rtsp_url: RTSP推流地址,如:rtsp://localhost:8554/live
    """
    # 打开视频文件
    cap = cv2.VideoCapture(input_file)
    if not cap.isOpened():
        print(f"无法打开视频文件:{input_file}")
        return

    # 获取视频属性
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    # 修复异常FPS
    if fps < 20 or fps > 120:
        print(f"⚠ 无效帧率 {fps}, 使用默认 30")
        fps = 30
    fps = int(fps)

    print(f"视频信息:{width}×{height} @ {fps}fps (原始值:{cap.get(cv2.CAP_PROP_FPS)})")

    # FFmpeg 命令 - 使用 mpeg1video 编码(兼容性好, 无需libx264)
    ffmpeg_cmd = [
        'ffmpeg',
        '-y',                       # 覆盖输出
        '-f', 'rawvideo',
        '-vcodec', 'rawvideo',
        '-pix_fmt', 'bgr24',        # Opencv 默认是 BGR
        '-s', f'{width}x{height}',  # 分辨率
        '-r', str(fps),             # 帧率
        '-i', '-',                  # 从 stdin 读取
        '-c:v', 'mpeg1video',       # 改为 mpeg1video
        '-b:v', '1000k',            # 码率(可调)
        '-f', 'rtsp',               # 输出格式
        rtsp_url
    ]

    # 启动FFmpeg进程
    process = subprocess.Popen(
        ffmpeg_cmd,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )

    def signal_handler(sig, frame):
        print("\n正在停止推流...")
        process.terminate()
        cap.release()
        sys.exit(0)

    signal.signal(signal.SIGINT, signal_handler)

    print(f"开始推流到:{rtsp_url}")
    print("按 Ctrl+C 停止推流")

    try:
        while True:
            ret, frame = cap.read()
            if not ret:
                print("⚠ 视频读取完毕, 循环播放")
                cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
                continue

            # 写入帧到 FFmpeg
            process.stdin.write(frame.tobytes())

    except BrokenPipeError:
        # FFmpeg 崩溃, 读取错误日志
        print("❌ FFmpeg 进程已崩溃, 可能编码器不支持或参数错误")
        try:
            stderr_output = process.stderr.read().decode()
            if stderr_output.strip():
                print("📚 FFmpeg 错误日志:")
                print(stderr_output)
        except:
            pass
    except Exception as e:
        print(f"❌ 推流异常:{e}")
    finally:
        process.terminate()
        try:
            process.wait(timeout=5)
        except subprocess.TimeoutExpired:
            process.kill()
        cap.release()

if __name__ == "__main__":
    input_file = "test.mp4"     # 替换为你的视频文件
    rtsp_url = "rtsp://localhost:8554/live"     # RTSP服务器地址
    push_file_to_rtsp(input_file, rtsp_url)

将代码中的变量 input_filertsp_url 就可执行脚本, 脚本会将 test.mp4 转换为 risp 格式推送到 RTSP 服务器, 并循环播放, 按 Ctrl+C 即可退出脚本

python3 stream_publisher.py

image

四、测试与验证

4.1 使用VLC播放

打开VLC → 文件 → 打开网络串流

image

输入:rtsp://localhost:8554/live ,点击播放

image

image

posted @ 2026-01-06 10:27  测试小罡  阅读(46)  评论(0)    收藏  举报