限时福利领取


背景与痛点

最近在做视频监控项目时,遇到了一个典型问题:摄像头输出的RTSP流在Web端兼容性极差。浏览器原生不支持RTSP协议,而传统的单进程转码方案在处理20路以上视频流时,CPU直接飙到100%,延迟高达10秒+。这显然无法满足实时监控的需求。

RTSP转HLS流程示意图

技术选型对比

  1. FFmpeg原生方案
  2. 优点:转码质量高,参数调节灵活
  3. 缺点:多路流管理复杂,需要自己处理进程调度

  4. GStreamer方案

  5. 优点:管道式处理流媒体更直观
  6. 缺点:学习曲线陡峭,社区资源较少

  7. Nginx作为分发器

  8. 成熟的HTTP服务,完美支持HLS协议
  9. 配合nginx-rtmp-module可实现动态切片
  10. 高并发性能优异,轻松支持100+路播放

核心实现步骤

1. 多路流并行转码

使用FFmpeg的-map参数同时处理多路流:

ffmpeg -i rtsp://cam1 -c:v libx264 -map 0 -f hls -hls_time 2 -hls_list_size 5 /hls/cam1.m3u8 &
ffmpeg -i rtsp://cam2 -c:v libx264 -map 0 -f hls -hls_time 2 -hls_list_size 5 /hls/cam2.m3u8 &

关键参数说明: - -hls_time 2:每个切片2秒 - -hls_list_size 5:保持5个切片在播放列表

2. Nginx配置优化

server {
    listen 80;
    location /hls {
        types {
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
        }
        root /tmp;
        add_header Cache-Control no-cache;
        add_header Access-Control-Allow-Origin *;
    }
}

Nginx配置效果图

3. 动态加载机制

使用inotify监控HLS目录变化,实现实时更新:

import pyinotify

wm = pyinotify.WatchManager()
mask = pyinotify.IN_CLOSE_WRITE

class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CLOSE_WRITE(self, event):
        print("New TS file:", event.pathname)

handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)
wdd = wm.add_watch('/hls', mask, rec=True)
notifier.loop()

完整Docker示例

FROM nginx:latest

RUN apt-get update && \
    apt-get install -y ffmpeg \
    python3 python3-pip \
    inotify-tools

COPY nginx.conf /etc/nginx/nginx.conf
COPY monitor.py /monitor.py

CMD service nginx start && \
    python3 /monitor.py &
    ffmpeg -i rtsp://cam1 -c:v libx264 -map 0 \
           -f hls -hls_time 2 -hls_list_size 5 \
           -hls_flags delete_segments /hls/cam1.m3u8

性能优化建议

  1. 硬件加速
  2. 使用-c:v h264_nvenc启用NVIDIA GPU加速
  3. -c:v h264_vaapi使用Intel核显加速

  4. 内存泄漏检测

    valgrind --leak-check=full ffmpeg -i input -c:v libx264 output
  5. IO优化

  6. 使用内存盘存储临时切片
  7. 或采用SSD存储

常见问题解决

  1. RTSP断流重连

    ffmpeg -reconnect 1 -reconnect_at_eof 1 \
           -reconnect_streamed 1 -i rtsp://cam
  2. 时间戳对齐

  3. 添加-avoid_negative_ts make_zero参数
  4. 或使用-use_wallclock_as_timestamps 1

延伸思考

虽然HLS已经能解决大部分场景需求,但对于需要超低延迟(<1s)的场景,可以考虑:

  1. 改用WebRTC协议
  2. 使用RTMP+HTTP-FLV组合
  3. 尝试LL-HLS(低延迟HLS)

这套方案在我们生产环境稳定运行了6个月,单台i7服务器能稳定处理120路720p转码,平均延迟控制在3秒内。希望这些实践经验对你有帮助!

Logo

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

更多推荐