使用FFmpeg将HLS转码为RTMP用于Nginx多播失败求助
从你的描述来看,之前用Teradek编码器推流正常,说明Nginx RTMP服务器本身是没问题的,问题应该出在FFmpeg转码环节或者HLS流的处理上。我给你几个排查方向和修正建议:
1. 修正FFmpeg命令的参数顺序和编码策略
你当前的FFmpeg命令里-re的位置不对,-re是用来让FFmpeg按照流的实际帧率读取输入,这个参数应该放在-i前面,否则它不会生效。另外,既然你的HLS流已经是H264视频和AAC音频(和RTMP兼容的编码格式),完全可以直接复制编码,不用重新转码——这样既节省服务器资源,又能避免编码参数不匹配的问题。
修正后的命令:
exec ffmpeg -re -i http://<HLS>.m3u8 -c:v copy -c:a copy -f flv rtmp://localhost/live/test;
如果还是不行,可以尝试添加一些RTMP兼容的兜底参数(原流已符合要求,大概率不需要,但可以试下):
exec ffmpeg -re -i http://<HLS>.m3u8 -c:v copy -c:a aac -ar 48000 -ac 2 -f flv rtmp://localhost/live/test;
2. 检查Nginx RTMP应用的多播配置
确保你的RTMP应用段配置里正确开启了多播,示例配置如下:
rtmp { server { listen 1935; chunk_size 4096; application live { live on; # 开启多播功能 multicast on; # 设置多播组地址和端口(可根据需求调整) multicast_group 224.0.0.1:1234; # 多播TTL值(默认1,跨网段传输需要调大) multicast_ttl 1; # 绑定多播网卡(服务器有多网卡时指定) # multicast_bind 0.0.0.0; } } }
注意:多播需要服务器所在网络支持,防火墙要放行对应的多播端口和UDP协议。
3. 查看FFmpeg和Nginx的日志排查错误
FFmpeg日志
在FFmpeg命令末尾加上-v debug,获取详细调试日志,比如:
exec ffmpeg -re -i http://<HLS>.m3u8 -c:v copy -c:a copy -f flv rtmp://localhost/live/test -v debug;
重点关注日志里的这些信息:
- 是否能正常读取HLS流(有没有404、连接超时、防盗链拦截提示)
- 有没有编码/封装格式不兼容的错误
- 能不能成功连接到Nginx RTMP服务器
Nginx日志
查看Nginx的错误日志(通常路径为/var/log/nginx/error.log),看看有没有RTMP模块相关的报错,比如FFmpeg进程启动失败、流推送被拒绝等。
4. 验证HLS流的可访问性
先单独用FFmpeg测试能不能读取HLS流并保存到本地,确认流本身没问题:
ffmpeg -re -i http://<HLS>.m3u8 -c copy test.flv
如果能生成正常的FLV文件,说明HLS流可正常读取,问题出在推送到RTMP的环节;如果不能生成,可能HLS流需要携带请求头(比如Referer、Cookie),这时可以给FFmpeg加-headers参数:
ffmpeg -re -headers "Referer: http://your-hls-domain.com/" -i http://<HLS>.m3u8 -c copy test.flv
5. 验证VLC的播放设置
确保VLC输入的RTMP地址正确,比如rtmp://localhost/live/test;如果是多播,也可以直接尝试播放多播地址rtmp://224.0.0.1:1234/live/test(根据你的Nginx配置调整)。另外可以尝试关闭VLC的硬件加速,或者调整缓冲时间,排除播放器本身的问题。
内容的提问来源于stack exchange,提问作者user9646948

