docker音视频服务采用ffmpeg转码容器与srs等流媒体服务器容器解耦架构,通过共享卷或rtmp推流协同工作;推荐jrottenberg/ffmpeg镜像与srs5组合,生产环境需集成nginx上传、redis队列和celery worker,并注意ssd存储、资源限制与健康检查。

用 Docker 实现音视频流媒体分发与转码服务,核心是把 FFmpeg(转码)和流媒体服务器(如 SRS、ZLMediaKit 或 rtsp-simple-server)解耦部署、协同工作。不靠单一大而全的镜像,而是按职责拆分:一个容器专注实时转码,一个容器专注协议分发,中间用网络或共享卷传递数据。这样既灵活又稳定,也方便横向扩展。
选对基础组件:FFmpeg + 流媒体服务器双容器架构
不要试图在一个容器里塞进所有功能。推荐组合:
-
转码层:用
jrottenberg/ffmpeg镜像(Alpine 轻量、预装常用编码器),或自定义构建支持vaapi(Intel)或nvenc(NVIDIA)的版本;检查是否含关键编码器:docker run --rm jrottenberg/ffmpeg -encoders | grep -E "(x264|x265|vp9|aac)" - 分发层:SRS5(适合 RTMP/HLS/HTTP-FLV 全链路)、ZLMediaKit(更轻、WebRTC 支持好)、或 rtsp-simple-server(纯协议路由,零转码,极低开销)
-
连接方式:转码容器输出 HLS 切片到共享目录,SRS 容器挂载该目录并启用
hls_path;或 FFmpeg 直接推流到 SRS 的 RTMP 地址(rtmp://srs:1935/live/stream)
快速验证:本地跑通推流转封装流程
先不加队列、不加上传,用最简命令验证链路是否通:
- 启动 SRS 容器:
docker run -d --name srs -p 1935:1935 -p 8080:8080 ossrs/srs:v5.0 - 用 FFmpeg 推一个测试文件:
docker run --rm -v $(pwd):/data jrottenberg/ffmpeg -re -i /data/test.mp4 -c:v libx264 -preset fast -c:a aac -f flv rtmp://localhost:1935/live/test - 浏览器访问
http://localhost:8080/players/srs_player.html,选择live/test拉流,确认能播
生产就绪:加入异步转码与状态管理
真实场景需应对大文件、并发任务和失败重试,建议补上三件套:
-
Nginx 前置上传:配置
client_max_body_size 4G,接收用户上传的原始视频,存入临时目录 -
Redis 任务队列:每个任务生成唯一
task_id,状态存为task:{id}(pending → running → done),输出路径、错误日志一并记录 -
Celery 或 Bull 后台 worker:监听队列,拉取任务后启动 FFmpeg 容器(
docker run --rm -v /storage:/data ...),转码完成后更新 Redis 状态,并触发 SRS 自动加载新 HLS 流
性能与稳定性关键点
容易忽略但影响上线效果的细节:
-
存储必须用 SSD:HLS 切片写入频繁,机械盘易成瓶颈;挂载时用
:rw,delegated(macOS)或:rw,rshared(Linux)避免 I/O 延迟 -
限制容器资源:CPU 绑定(
--cpus="2")、内存上限(--memory=2g),防止单个转码吃光宿主机资源 -
FFmpeg 进度反馈:加
-progress pipe:1,解析 JSON 输出到 Redis,供前端查进度(如{"out_time_ms":"123456789","progress":"continue"}) -
健康检查不可少:SRS 加
curl -sf http://localhost:1985/api/v1/versions,FFmpeg 容器加ffmpeg -version,Dockerfile 里写HEALTHCHECK











