4. 流媒体服务器搭建:Live555安装与配置、FFmpeg推流与拉流、GStreamer管道搭建
这一章我们直接动手。流媒体服务器是整个音画同步系统的核心,说白了,摄像头推上来的 RTSP 流得先有个地方接着,播放器才能拉走。我个人习惯把服务器、推流端、拉流端分开搭,这样排查问题的时候思路特别清晰。
4.1 Live555 安装与基础配置
Live555 是目前最主流的 RTSP 服务器库,很多商业 IP Camera 和 NVR 底层都在用。它轻量、稳定,但编译方式有点老派——没有 cmake,得用它的 genMakefiles 脚本。
4.1.1 下载与编译
# 下载源码
wget http://www.live555.com/liveMedia/public/live555-latest.tar.gz
tar -xzf live555-latest.tar.gz
cd live
# 生成 Makefile(以 Linux 为例)
./genMakefiles linux
# 编译
make -j$(nproc)
编译完会在 liveMediaServer/ 目录下生成 live555MediaServer 可执行文件。嗯,这里要注意:如果你的系统是 Ubuntu 22.04 以上,可能需要先装 build-essential 和 openssl-dev,否则编译会报错。
./genMakefiles linux-with-openssl,开启加密支持。虽然 RTSP 本身不强制加密,但很多现代播放器(如 VLC 新版)默认会尝试 TLS 连接,没开加密反而会握手失败。
4.1.2 启动服务器
# 默认端口 8554,媒体文件目录为当前目录
./live555MediaServer
# 指定端口和媒体目录
./live555MediaServer -p 8554 -m /data/media
启动后,服务器会自动扫描媒体目录下的 .264、.mp3、.mkv 等文件,并为每个文件生成一个 RTSP 地址。比如目录下有个 test.h264,那它的 RTSP 地址就是 rtsp://你的IP:8554/test.h264。
testOnDemandRTSPServer 或者自己写一个代理。我一开始直接用 live555MediaServer 接推流,结果播放器一直报 404,排查了半天才发现是服务器类型选错了。
4.2 FFmpeg 推流与拉流
FFmpeg 是流媒体界的瑞士军刀。推流、拉流、转码、切片,几乎什么都能干。这一节我们只聚焦 RTSP 场景下的推拉流操作。
4.2.1 推流到 Live555
Live555 的 testOnDemandRTSPServer 可以接收 RTP 推流。我们需要先启动这个服务端,然后用 FFmpeg 把本地视频或摄像头数据推过去。
# 步骤1:启动 Live555 的接收端(在 live/testProgs 目录下)
./testOnDemandRTSPServer 8554
# 步骤2:FFmpeg 推流(从本地文件)
ffmpeg -re -i input.mp4 \
-c:v libx264 -preset ultrafast -tune zerolatency \
-c:a aac -ar 44100 -ac 2 \
-f rtsp rtsp://localhost:8554/live/stream
# 从摄像头推流
ffmpeg -f v4l2 -i /dev/video0 \
-c:v libx264 -preset ultrafast -tune zerolatency \
-f rtsp rtsp://localhost:8554/live/cam
参数说明:-re 表示按原始帧率读取,不加速;-preset ultrafast 和 -tune zerolatency 是低延迟编码的关键,你想想看,如果编码延迟 2 秒,音画同步做得再好也没用。
4.2.2 拉流播放
拉流就简单多了,FFmpeg 可以直接播放或转存 RTSP 流。
# 直接播放
ffplay rtsp://localhost:8554/live/stream
# 拉流并保存到本地文件
ffmpeg -i rtsp://localhost:8554/live/stream \
-c copy output.mp4
# 拉流并实时转码(降低分辨率)
ffmpeg -i rtsp://localhost:8554/live/stream \
-vf scale=640:360 -c:v libx264 -preset fast \
-c:a aac output_small.mp4
-rtsp_transport tcp 强制走 TCP 传输,虽然延迟会高一点,但稳定性好很多。等调通了再切回 UDP 追求低延迟。
4.3 GStreamer 管道搭建
GStreamer 比 FFmpeg 更灵活,适合做复杂的管道处理。它的核心思想是「插件 + 管道」,每个环节都是一个 element,用 ! 串联起来。
4.3.1 基础管道结构
一个典型的 RTSP 拉流管道长这样:
# 拉流并显示
gst-launch-1.0 rtspsrc location=rtsp://localhost:8554/live/stream \
! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink
# 带音频的完整管道
gst-launch-1.0 rtspsrc location=rtsp://localhost:8554/live/stream \
! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink \
rtspsrc. ! rtppcmadepay ! alawdec ! audioconvert ! autoaudiosink
这里有个细节:rtspsrc 会自动分离视频和音频流,通过 . 语法分别接到不同的解码器上。我在项目中遇到过,如果音频编码不是 PCM A-law,得换成对应的 depay 插件,比如 rtpmp4gdepay 或 rtpopusdepay。
4.3.2 推流管道
GStreamer 也能推流,不过比 FFmpeg 复杂一些,需要手动组装 RTP 打包器。
# 从摄像头推流到 RTSP 服务器
gst-launch-1.0 v4l2src device=/dev/video0 \
! videoconvert ! x264enc tune=zerolatency speed-preset=ultrafast \
! rtph264pay ! udpsink host=127.0.0.1 port=5000
# 注意:这里推的是裸 RTP,需要配合 Live555 的 RTP 接收端使用
rtspclientsink 插件(GStreamer 1.20+ 版本才支持)。老版本的话,我建议还是用 FFmpeg 推流,GStreamer 拉流,各取所长。
4.4 本章知识体系
下面这张图把本章的核心链路和组件关系梳理清楚了,建议你保存下来对照着搭环境。
4.5 三种方案的对比与选型
我把三种工具的核心差异整理成了表格,方便你根据实际场景选择。
| 功能维度 | Live555 | FFmpeg | GStreamer |
|---|---|---|---|
| 角色定位 | RTSP 服务器 | 推流/拉流/转码工具 | 管道式多媒体框架 |
| 推流支持 | 需配合 testOnDemand | 原生支持(-f rtsp) | 需 rtspclientsink 插件 |
| 拉流支持 | 不适用(服务器端) | 原生支持(ffplay/ffmpeg) | 原生支持(rtspsrc) |
| 延迟控制 | 中等(依赖推流端) | 优秀(-tune zerolatency) | 优秀(tune=zerolatency) |
| 学习曲线 | 低(开箱即用) | 中(参数多但文档全) | 高(管道概念需理解) |
| 适用场景 | 生产环境服务器 | 快速验证/转码/录制 | 复杂管道/定制化处理 |
4.6 常见问题与排查思路
搭建过程中你可能会遇到下面这些问题,我把排查步骤列出来:
- 推流成功但拉流黑屏:检查编码参数,H.264 的 profile 不要用 high10,很多播放器不支持。改成 baseline 或 main 试试。
- RTSP 连接超时:防火墙有没有开 8554 端口?用
telnet IP 8554测试一下端口连通性。 - 音画不同步:先确认推流端的
-vsync和-async参数,然后在拉流端用-fflags nobuffer减少缓冲。 - GStreamer 管道报错 "No such element":缺插件。运行
gst-inspect-1.0 插件名检查是否安装,没装的话apt install gstreamer1.0-plugins-*一把梭。
-march=armv7-a,导致二进制指令集不兼容。所以跨平台编译时,一定要确认目标 CPU 架构和浮点运算单元(硬浮点/软浮点)是否匹配。
好了,这一章的内容就到这里。服务器搭起来之后,下一件重要的事就是让音画真正同步起来——那是我们第 5 章要啃的硬骨头。