尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用Docker部署SRS流媒体服务器:从RTMP到WebRTC的完整实践

用Docker部署SRS流媒体服务器:从RTMP到WebRTC的完整实践 说实话我最早接触 SRS 是在一个监控项目上当时要在服务器上编译安装依赖库装了一堆中间还因为 glibc 版本问题折腾了大半天。后来换成了 Docker 部署 SRS从拉镜像到推拉流成功前后不超过五分钟。自此以后我在所有项目里都用容器化方案跑 SRS再也没碰过裸机编译。SRSSimple Realtime Server是目前开源社区里非常活跃的流媒体服务器天然支持 RTMP、HLS、WebRTC、SRT、HTTP-FLV 等主流协议。配合 Docker 使用能快速在本地或云服务器上搭建一套完整的实时音视频直播平台支持摄像头 RTSP 转直播、OBS 推流、WebRTC 低延迟连麦、HLS 点播回放等场景。这篇内容适合刚接触流媒体的新手也适合想快速验证业务逻辑的团队参考。1. 为什么用 Docker 跑 SRS方案选型的底层逻辑1.1 SRS 的协议栈到底强在哪里先说一个我拿 SRS 做项目的直观感受它不是一个“只能推 RTMP 流”的玩具服务器而是一个覆盖音视频接入、转封装、分发全过程的集成式服务。比如某个项目中前端需要低延迟直播我直接接入 WebRTC 播放另一个业务要兼容 iOS Safari又把 HLS 同时开起来。一套 SRS 服务全部兜住完全不用再单独部署其他组件。从协议支持上看SRS 支持 RTMP、RTSP、HTTP-FLV、HLS、WebRTC、SRT、GB28181 等多种接入和播放协议。其中 RTMP 是直播推流的主流协议OBS、FFmpeg 都原生支持HLS 则天然适配移动端和普通 Web 播放器WebRTC 则能把延迟压到 500ms 以内适合连麦和视频会议场景。正是这种“多协议握手”的能力让它能独立承担一整条直播链路的源头服务。1.2 Docker 化部署解决了哪些传统痛点用 Docker 跑 SRS最大的收益不是省掉了编译时间而是把“环境一致性”这个隐藏成本直接抹掉了。早些年我在 CentOS 7 上编译 SRS要手动装 gcc、make、pcre-devel、openssl-devel 等一堆依赖中途还要处理 EPEL 源偶尔抽风的问题。一旦换一台服务器哪怕系统版本一模一样也可能因为某个库版本不一致而编译失败。这类重复劳动对业务来说完全是纯消耗。Docker 方案把 SRS 及其依赖封装成镜像启动就是完整运行时彻底绕开了服务器系统差异。我实际测试过同一份ossrs/srs:5镜像在 Ubuntu 22.04、Debian 12、CentOS Stream 9 上跑出来的行为完全一致这在排查跨环境问题时非常省心。另外 Docker 带来的还有版本回滚能力升级 SRS 时先 pull 新镜像启动测试有问题随时切回旧容器整个回滚过程秒级完成。1.3 何时不建议用 Docker 部署 SRS这不是劝退而是给你排雷。如果你的服务器本身资源极其紧张比如只有 256MB 内存的极小 VPS或者有非常底层的网络调优需求比如自定义内核参数、绑定网卡队列那裸机部署可能更合适。但绝大多数场景下Docker 的资源开销可以忽略不计。还有一种情况是团队已经有成熟的裸机运维体系比如用 systemd 管服务的习惯根深蒂固强行引入 Docker 反而增加学习成本这时才需要权衡。2. 部署前必做准备Docker 环境与镜像源配置2.1 安装 DockerWindows 与 Linux 双路线如果你本机是 Windows建议直接用 Docker Desktop。它自带图形化管理界面资源占用相较于虚拟机方案低很多。安装流程很常规装好后在 Settings 里把 WSL 2 后端选上就行。需要注意一点Docker Desktop 若未启动后续所有docker命令都会报连接失败所以每次用之前先确认小鲸鱼图标在正常运行。Linux 服务器上安装则推荐用官方脚本CentOS、Ubuntu 均适用。执行完安装脚本后把当前用户加入 docker 组否则每次执行 docker 命令都要加sudo非常影响效率。命令如下curl -fsSL https://get.docker.com | bash sudo usermod -aG docker $USER重新登录终端后执行docker version确认安装成功。2.2 镜像拉取慢配置可靠镜像源这是被问得最多的一个问题。平时docker pull ossrs/srs:5时默认从 Docker Hub 拉取网络波动或延迟都会导致超时。常规思路是给 Docker 配置镜像源。这里直接说配置方法Linux 下编辑/etc/docker/daemon.json没有就新建Windows/Docker Desktop 则在 Settings - Docker Engine 里改同样的 JSON 内容{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com, https://docker.mirrors.ustc.edu.cn ] }保存后重启 Docker 服务Linux 执行sudo systemctl restart docker。配置完成后重新拉镜像速度体感会快不少。但我必须提醒一句公共镜像源的稳定性无法保证如果某天发现一个源失效换列表里另一个即可。项目真实上线阶段有条件就把镜像同步到私有仓库这才是根治方案。2.3 端口规划哪些端口是必须的SRS 涉及的端口比较多部署前先规划好能避免很多冲突。SRS 5 的最低端口集合如下端口协议用途1935TCPRTMP 推流与拉流8080TCPHTTP-FLV、HLS、WebRTC 播放与访问 API1985TCPHTTP API查询服务器状态8000UDPWebRTC 媒体传输如果只是先跑通 RTMP 推流和 HLS 播放1935 和 8080 就够用了。但既然上了 Docker建议把这些端口一次性映射好省得后面想玩 WebRTC 时再回来改配置。3. 五分钟跑通Docker 部署 SRS 完整实操3.1 拉镜像并启动容器确保 Docker 就绪后先拉取 SRS 5 的官方镜像这是当前最推荐的稳定版本docker pull ossrs/srs:5镜像拉取完成后直接启动容器。下面这条命令覆盖了 RTMP、HTTP、API 和 WebRTC 端口的映射docker run -d --name srs \ -p 1935:1935 \ -p 8080:8080 \ -p 1985:1985 \ -p 8000:8000/udp \ ossrs/srs:5启动后执行docker ps看到状态为 Up 就算成功。如果看到端口被占用用docker logs srs查看日志一般会直接提示是 bind 失败还是启动故障。3.2 验证服务访问 HTTP API 与自带控制台容器启动后怎么确认 SRS 真的在正常工作最直接的方法是请求它的 HTTP API 接口curl http://localhost:1985/api/v1/versions正常情况下会返回一段包含版本号、服务标识的 JSON 字符串这代表 API 服务已经就绪。接着在浏览器中访问http://localhost:8080/players/srs_player.html这是 SRS 自带的播放器测试页。能打开这个页面说明静态资源服务和 HTTP 服务都正常了。3.3 从推流到播放体验真实直播链路服务跑起来了现在进入最有成就感的环节推流和播放。先用 OBS 推流。打开 OBS进入设置 - 直播服务选“自定义”服务器地址填rtmp://localhost:1935/live推流码填livestream。然后开始推流这相当于把直播画面推给了 SRS。接着打开 SRS 自带播放器测试页在播放地址栏输入rtmp://localhost:1935/live/livestream如果一切正常画面几乎瞬间就能出来。我还习惯顺手测一下 HLS 线路把播放地址换成http://localhost:8080/live/livestream.m3u8浏览器直接访问这个 m3u8 地址能播放就代表 HLS 走通了。这时你已经具备了一套完整的直播系统雏形整个过程不超过五分钟。4. 从体验到生产docker-compose 编排与配置详解4.1 用 Docker Compose 固化部署环境一个人玩的时候docker run 敲几次没问题但项目要交付或上生产就必须把部署过程变成“文档化、可版本管理”的形式。Docker Compose 是我在这个阶段的首选工具。它的好处是把端口映射、数据卷、环境变量、重启策略全部写进一个 YAML 文件团队里任何人拿到文件都能一键拉起完全一致的环境。下面是我常用的一份docker-compose.yml模板version: 3.8 services: srs: image: ossrs/srs:5 container_name: srs-app restart: always ports: - 1935:1935 - 8080:8080 - 1985:1985 - 8000:8000/udp volumes: - ./srs.conf:/usr/local/srs/conf/srs.conf - ./data:/usr/local/srs/objs environment: - TZAsia/Shanghai这里有两个细节值得说明。一个是restart: always服务器重启后容器会自动拉起省去手动干预另一个是挂载./data:/usr/local/srs/objsSRS 的 HLS 切片、DVR 录制文件都保存在这个目录下挂载到宿主机后数据不会因为容器删除而丢失。在项目目录下执行docker compose up -d看到 “Started” 状态就完成了。以后想升级改掉镜像版本号再docker compose up -d即可。4.2 SRS 配置文件的常见模块解读SRS 默认配置在/usr/local/srs/conf/srs.conf里面核心模块要能看懂才能应对不同场景的定制需求。先说监听配置listen 1935; max_connections 1000;listen指定 RTMP 的服务端口max_connections限制并发连接数。如果你的服务面向公网这个值要根据服务器带宽和内存来定不建议盲目加大。接着是 HTTP 模块http_api { enabled on; } http_server { enabled on; listen 8080; }http_api开启后外部可以通过 1985 端口查询服务器状态、踢人、获取流列表等信息很适合对接运维系统。http_server用来托管 HLS 文件和 Web 播放器页面所以 HLS 播放依赖它。然后是 vhost 配置。SRS 里 vhost 类似 Nginx 的 server 块可以为不同的域名或业务配置不同策略。默认配置里有一个__defaultVhost__代表所有未匹配域名的流都走这里vhost __defaultVhost__ { hls { enabled on; } }在这个 vhost 块里开启了 HLSSRS 会把 RTMP 流转封装成 HLS 切片并生成 m3u8 索引文件。HLS 通常还要配套设置分片时长和窗口大小hls { enabled on; hls_path ./objs/nginx/html; hls_fragment 5; hls_window 30; }hls_fragment是每个切片文件的时长单位秒hls_window是播放窗口总时长。切片越短延迟越低但切片文件越多对磁盘 IO 的要求也越高。直播场景我一般设置 5 秒切片、30 秒窗口兼顾延迟和稳定性。4.3 自定义配置加鉴权、开 WebRTC 与 HLS默认配置只是“能用”真实项目里肯定要动刀。先说最实用的鉴权。SRS 支持在播放和推流时校验密钥防止任何人都能推拉流。在 vhost 块里加入vhost __defaultVhost__ { play { secret your_play_secret; } publish { secret your_publish_secret; } }这样配置后拉流地址必须带?secretyour_play_secret才能播放推流地址同理。实际使用中这个密钥最好由后端服务生成并配合时间戳做短期有效避免长期暴露在抓包环境中。再来说 WebRTC。默认配置下 SRS 是没有开启 WebRTC 的需要显式配置 rtc_server 模块rtc_server { enabled on; candidate $CANDIDATE; }candidate是你的服务器公网 IP 或域名。注意如果服务器在 NAT 后面这一步必须正确配置否则 WebRTC 协商阶段会直接失败表现为媒体流始终处于“connecting”状态。完整配置示例参考listen 1935; max_connections 1000; daemon off; srs_log_tank console; http_api { enabled on; } http_server { enabled on; listen 8080; dir ./objs/nginx/html; } rtc_server { enabled on; candidate your.public.ip; } vhost __defaultVhost__ { hls { enabled on; hls_path ./objs/nginx/html; hls_fragment 5; hls_window 30; } play { secret your_play_secret; } publish { secret your_publish_secret; } }这份配置已经能覆盖绝大多数中小直播业务自测足够上线也能顶一阵。5. 进阶玩法与生态联动5.1 用 FFmpeg 把视频文件变成直播流除了 OBS 推流另一个高频场景是把本地视频文件模拟成实时直播流。刚好 SRS 生态里最常用的搭档就是 FFmpeg。FFmpeg 可以用-re参数按帧率真实读取文件并推送命令如下ffmpeg -re -i ./movie.mp4 -c copy -f flv rtmp://localhost:1935/live/movie-re很关键它让 FFmpeg 以原始帧率读取文件模拟摄像头实时输出的效果。如果不加FFmpeg 会以最快速度推完整个文件直播画面秒变快进。这个玩法适合做 24 小时直播频道、影视轮播、宣传片循环等场景。后期如果想让视频循环推送套一层 shell 循环脚本即可。5.2 接入 WebRTC低延迟播放与连麦如果业务对延迟有硬性要求比如在线答题、远程指导、互动连麦WebRTC 是绕不开的方向。SRS 5 对 WebRTC 的支持已经相当成熟其中rtc_server完成媒体传输信令部分可以由自研后端或对接现成信令服务实现。WebRTC 拉流地址格式为webrtc://your.domain:8080/live/livestream对应的播放器可以用 SRS 自带的srs_player.html切换 webrtc 模式测试。低延迟的体验不是玄学实测同一网络环境内RTMP 播放延迟约 2-3 秒WebRTC 能压到 500ms 左右。这对于在线教育中的白板互动、远程手术示教这类敏感场景是完全不同的产品体验。5.3 监控摄像头 RTSP 取流转推公网直播另一个经常在项目里遇到的场景是把海康、大华之类的 IP 摄像头的 RTSP 流转推到 SRS实现公网观看。摄像头本身不支持 RTMP 推流需要中间借助 FFmpeg 做协议转换。假设摄像头 RTSP 地址是rtsp://user:password192.168.1.100:554/Streaming/Channels/101推流命令如下ffmpeg -rtsp_transport tcp -i rtsp://user:password192.168.1.100:554/Streaming/Channels/101 \ -c copy -f flv rtmp://localhost:1935/live/camera1这里特意用了-rtsp_transport tcp因为 UDP 传输在跨网段时容易丢包花屏TCP 稳定性好很多。转流成功后SRS 侧再做 HLS 切片或 WebRTC 分发外部用户就能通过网页看监控画面了。我做过一个项目把 16 路摄像头转推到 SRS再通过 H5 页面集中展示一台 4C8G 的服务器跑得稳稳当当。6. 常见问题与排查技巧实录6.1 容器启动失败端口占用与配置语法NaN6.2 推流成功但播放黑屏或卡顿NaN6.3 WebRTC 一直连接中无法出画面NaN6.4 HLS 延迟越来越大切片时间戳错乱NaN
返回列表