
1. 为什么需要低延迟直播系统直播行业的爆发式增长让低延迟成为刚需。想象一下体育赛事直播时观众比现场慢30秒或者电商直播时主播喊3、2、1上链接后用户半天看不到商品这种体验有多糟糕。传统直播方案中HLS协议通常有10-30秒延迟这在很多实时互动场景中完全不可接受。我去年帮一个在线教育客户搭建直播系统时就踩过这个坑。刚开始用普通HLS方案老师提问后学生反应总是慢半拍课堂互动完全进行不下去。后来改用Nginxnginx-http-flv-module方案把延迟压到1秒内才真正解决了问题。目前主流直播协议中RTMP延迟1-3秒但浏览器不支持FLV over HTTP延迟2-5秒兼容浏览器HLS延迟10-30秒兼容性最好WebRTC延迟1秒但配置复杂我们的目标是用Nginx搭建一个同时支持RTMP、FLV和HLS的混合方案既保证低延迟又兼顾兼容性。nginx-http-flv-module这个神器就能完美实现这个需求它基于nginx-rtmp-module开发增加了HTTP-FLV支持实测延迟可以控制在3秒以内。2. 环境准备与模块编译2.1 系统环境检查在开始前建议使用Ubuntu 20.04 LTS或CentOS 7系统。我两个系统都试过个人更推荐Ubuntu依赖问题少很多。先检查基础环境# 检查系统版本 cat /etc/os-release # 检查gcc版本 gcc --version # 检查make工具 make -v如果缺少基础编译工具用以下命令安装# Ubuntu/Debian sudo apt update sudo apt install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev git # CentOS/RHEL sudo yum install -y gcc make pcre pcre-devel zlib zlib-devel openssl openssl-devel git2.2 获取Nginx源码与模块首先确认现有Nginx版本如果已安装nginx -V重点保存configure arguments后面的内容待会重新编译要用。然后下载对应版本的Nginx源码wget http://nginx.org/download/nginx-1.18.0.tar.gz tar zxvf nginx-1.18.0.tar.gz接着获取nginx-http-flv-module源码git clone https://github.com/winshining/nginx-http-flv-module.git这个模块有几个优势值得注意完全兼容nginx-rtmp-module所有功能新增HTTP-FLV支持浏览器可直接播放支持GOP缓存降低首屏时间内存占用优化实测比原生rtmp-module低15%3. 编译安装带FLV模块的Nginx3.1 编译配置进入Nginx源码目录使用之前的configure参数并添加新模块cd nginx-1.18.0 ./configure \ --prefix/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_realip_module \ --add-module../nginx-http-flv-module这里有个坑要注意如果之前安装过Nginx必须使用完全相同的configure参数否则可能导致兼容性问题。我第一次编译时就因为漏了--with-http_ssl_module导致现有HTTPS站点全部报错。3.2 编译与安装执行编译make编译完成后不要直接make install这样会覆盖现有配置。正确做法是只替换二进制文件# 停止Nginx sudo systemctl stop nginx # 备份旧文件 sudo cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak # 替换新文件 sudo cp objs/nginx /usr/local/nginx/sbin/nginx # 检查模块是否加载成功 nginx -V | grep flv如果看到--add-module../nginx-http-flv-module就说明成功了。启动Nginx后我们就有了一个支持RTMP和HTTP-FLV的流媒体服务器。4. 配置多协议直播服务4.1 基础RTMP配置在nginx.conf的http块同级添加rtmp配置rtmp { server { listen 1935; chunk_size 4096; notify_method get; application live { live on; meta copy; # 重要开启GOP缓存 gop_cache on; # 允许所有推拉流 allow publish all; allow play all; } } }关键参数解析chunk_size数据块大小影响传输效率gop_cache缓存关键帧降低首屏时间meta copy保留元数据确保播放器兼容性4.2 HTTP-FLV与HLS配置在http块内添加以下server配置server { listen 8080; location /flv { flv_live on; chunked_transfer_encoding on; add_header Access-Control-Allow-Origin *; } location /hls { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } alias /tmp/hls; expires -1; } }这样我们就实现了RTMP推流rtmp://server:1935/live/streamkeyHTTP-FLV播放http://server:8080/flv?applivestreamstreamkeyHLS播放http://server:8080/hls/streamkey.m3u85. 推流与播放实战5.1 使用OBS推流OBS设置要点场景收集建议至少包含视频采集浏览器源输出设置编码器x264或硬件编码码率建议2000-6000kbps关键帧间隔2秒影响延迟推流地址rtmp://your-server-ip/live/stream_key实测发现关键帧间隔对延迟影响最大。设为1秒时延迟最低但会增大带宽消耗。建议电商直播用1秒普通直播用2秒。5.2 多端播放方案对比桌面端推荐方案VLC播放RTMP流延迟最低1-2秒命令vlc rtmp://server:1935/live/stream_key浏览器端方案HTTP-FLVflv.jsscript srchttps://cdn.jsdelivr.net/npm/flv.jslatest/script video idvideo/video script if(flvjs.isSupported()) { var player flvjs.createPlayer({ type: flv, url: http://server:8080/flv?applivestreamstream_key }); player.attachMediaElement(video); player.load(); player.play(); } /script实测延迟2-3秒HLShls.jsscript srchttps://cdn.jsdelivr.net/npm/hls.jslatest/script video idvideo/video script if(Hls.isSupported()) { var hls new Hls(); hls.loadSource(http://server:8080/hls/stream_key.m3u8); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED,function() { video.play(); }); } /script实测延迟10-15秒移动端方案iOS原生支持HLS直接使用video标签Android推荐使用flv.js或ijkplayer6. 性能优化与问题排查6.1 延迟优化技巧关键参数调优rtmp { server { gop_cache on; # 开启GOP缓存 idle_streams off; # 禁用空闲流检测 buflen 1000; # 缓冲区长度(ms) } }OBS设置建议使用低延迟编码预设关闭B帧增加延迟音频编码使用AAC-LC网络优化开启TCP_NODELAY调整内核网络参数echo net.ipv4.tcp_slow_start_after_idle0 /etc/sysctl.conf sysctl -p6.2 常见问题解决问题1首屏时间过长检查gop_cache是否开启确保OBS关键帧间隔≤2秒增加服务器带宽问题2播放卡顿# 查看Nginx连接状态 ss -s # 监控带宽 iftop -i eth0问题3时间戳不同步在OBS中开启使用系统时间戳选项7. 高级功能扩展7.1 多分辨率转码通过Nginx的exec模块调用FFmpeg实现application live { live on; exec ffmpeg -i rtmp://localhost/live/$name -c:a aac -b:a 128k -c:v libx264 -b:v 2500k -f flv rtmp://localhost/high/$name -c:a aac -b:a 64k -c:v libx264 -b:v 1000k -s 1280x720 -f flv rtmp://localhost/medium/$name -c:a aac -b:a 32k -c:v libx264 -b:v 600k -s 640x360 -f flv rtmp://localhost/low/$name; }7.2 直播录制配置application live { live on; record all; record_path /var/rec; record_unique on; record_suffix -%Y%m%d%H%M%S.flv; # 录制分段 record_interval 30m; }7.3 鉴权与安全application live { live on; # 推流鉴权 on_publish http://auth-server/auth/publish; # 播放鉴权 on_play http://auth-server/auth/play; # 防盗链 secure_link on; secure_link_md5 $secure_link_expires$uri$remote_addr secret; }在实际项目中这套方案已经支撑过单机5000并发直播流平均延迟控制在3秒内。最关键的是要合理配置缓冲区大小和GOP参数这两个对延迟影响最大。