Nginx集成nginx-http-flv-module:一站式搭建支持RTMP、HLS与HTTP-FLV的流媒体服务器

Nginx集成nginx-http-flv-module:一站式搭建支持RTMP、HLS与HTTP-FLV的流媒体服务器
1. 为什么选择nginx-http-flv-module搭建流媒体服务器现在做直播开发的朋友们应该都遇到过这样的烦恼RTMP协议延迟低但浏览器不支持HLS兼容性好但延迟高得让人抓狂。我去年给一个教育机构做在线课堂项目时就深有体会当老师提问时学生要等5-10秒才能回应课堂互动体验非常糟糕。后来改用nginx-http-flv-module方案后延迟直接降到1秒内效果立竿见影。nginx-http-flv-module这个神器其实是nginx-rtmp-module的增强版它最大的优势就是能同时支持RTMP、HLS和HTTP-FLV三种协议。简单来说就是RTMP负责接收推流比如用OBS推流HTTP-FLV给网页端提供低延迟播放HLS作为保底方案兼容苹果设备实测下来HTTP-FLV的延迟基本能控制在1-3秒而传统HLS通常要6秒以上。这个差距在电商直播带货时特别明显——主播喊3、2、1上链接时用HLS的用户看到的是主播还在介绍产品而用HTTP-FLV的观众已经能抢购了。2. 环境准备与模块编译2.1 安装必备依赖在开始之前建议使用Ubuntu 20.04 LTS或CentOS 7以上系统。我习惯先用下面这条命令把所有基础依赖装齐# Ubuntu/Debian sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev git # CentOS/RHEL sudo yum install -y gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel这里有个小坑要注意openssl版本最好在1.1.1以上否则可能遇到TLS协议兼容性问题。曾经有次在CentOS 7上默认装的openssl 1.0.2导致HLS在iOS上播放异常折腾了半天才发现是这个问题。2.2 下载源码并编译我推荐用nginx 1.20.x的稳定版和nginx-http-flv-module的v1.2.10版本搭配最稳。具体操作# 下载源码 wget http://nginx.org/download/nginx-1.20.2.tar.gz git clone https://github.com/winshining/nginx-http-flv-module.git # 解压并编译 tar zxvf nginx-1.20.2.tar.gz cd nginx-1.20.2 ./configure --prefix/usr/local/nginx \ --add-module../nginx-http-flv-module \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_flv_module \ --with-http_mp4_module make -j$(nproc) sudo make install编译参数说明--with-http_ssl_module支持HTTPS推流/拉流--with-http_v2_module开启HTTP/2提升传输效率--with-http_flv_module和--with-http_mp4_module支持点播功能编译完成后可以用nginx -V查看是否包含nginx-http-flv-module模块。如果看到下面这样的输出就说明成功了nginx version: nginx/1.20.2 built with OpenSSL 1.1.1f configure arguments: --add-module../nginx-http-flv-module3. 服务器配置详解3.1 基础配置模板这是我经过多个项目验证的稳定配置直接保存为/usr/local/nginx/conf/nginx.confworker_processes auto; rtmp_auto_push on; events { worker_connections 1024; } rtmp { server { listen 1935; chunk_size 4096; application live { live on; meta off; # 兼容flv.js # HLS配置 hls on; hls_path /tmp/hls; hls_fragment 2s; hls_playlist_length 6s; # HTTP-FLV配置 dash on; dash_path /tmp/dash; # 录制功能可选 record all; record_path /var/rec; record_unique on; } } } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; location / { root html; index index.html; } # HLS播放端点 location /hls { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } alias /tmp/hls; add_header Cache-Control no-cache; add_header Access-Control-Allow-Origin *; } # HTTP-FLV播放端点 location /flv { flv_live on; chunked_transfer_encoding on; add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Credentials true; } # 统计页面 location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root /path/to/nginx-http-flv-module; } } }3.2 关键参数调优根据我的实战经验这几个参数对性能影响最大hls_fragment切片时长建议2-4秒值越小延迟越低但会增加服务器负载值越大兼容性越好但延迟会升高chunk_sizeRTMP分块大小直播推荐4096点播可以加大到8192worker_processes工作进程数设置为CPU核心数用auto让nginx自动检测也行worker_connections单个进程连接数计算公式最大连接数 worker_processes × worker_connections直播场景建议至少10244. 推流与播放实战4.1 使用OBS推流OBS设置很简单进入设置→推流服务选择自定义服务器填rtmp://你的服务器IP/live串流密钥随便填比如test123推流地址实际是rtmp://你的服务器IP/live/test1234.2 多种播放方式对比根据我的测试数据播放方式延迟兼容性适用场景RTMP1-3秒差桌面端应用HTTP-FLV1-3秒中网页直播HLS6-30秒极好移动端/跨平台网页播放推荐方案script srchttps://cdn.jsdelivr.net/npm/flv.jslatest/script video idvideoElement controls/video script if (flvjs.isSupported()) { var flvPlayer flvjs.createPlayer({ type: flv, url: http://你的服务器IP/flv?applivestreamtest123 }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); flvPlayer.play(); } /script移动端HLS备用方案video srchttp://你的服务器IP/hls/test123.m3u8 controls/video5. 常见问题排查问题1推流成功但播放黑屏检查OBS输出格式是否为H.264 AAC确认nginx的hls_path目录有写入权限问题2HTTP-FLV延迟突然增大用netstat -antp查看服务器连接数调整worker_connections和worker_processes问题3HLS在iOS上无法播放确保m3u8文件的Content-Type是application/vnd.apple.mpegurl检查TS切片是否包含AAC音频流问题4高并发时卡顿开启nginx的rtmp_auto_push多worker模式考虑用ffmpeg做转码分流记得第一次上线时遇到个奇葩问题某些安卓手机播放FLV会花屏。后来发现是这些设备不支持High Profile的H.264编码在OBS里把编码配置改为Main Profile就解决了。这也提醒我们实际部署时一定要用真实设备做充分测试。