ffmpeg的-stream_loop -1参数对HLS输入无效问题求助
嘿,我刚好碰到过类似的问题!你遇到的情况其实是因为-stream_loop参数对HLS这种基于播放列表的输入格式支持有局限,咱们来一步步解决它。
首先先把你的问题再明确下:你用这条命令尝试循环推HLS到RTMP:
ffmpeg -stream_loop -1 -fflags +igndts -hide_banner -re -i playlist_main2_c.m3u8 -c copy -f flv -flvflags no_duration_filesize rtmp:****** -loglevel verbose
但播放完最后一个TS分片后就报错,错误信息如下:
[AVIOContext @ 0x7f8c42705080] Statistics: 362088 bytes read, 0 seeks296.7kbits/s speed=1.01x
Seek to start failed.
playlist_main2_c.m3u8: Operation not permitted-stream_loop -1完全没起到循环的作用。
问题原因
HLS的核心是一个.m3u8文本播放列表,ffmpeg在处理完所有分片后,尝试重置播放指针重新读取列表时,会因为HLS格式的索引特性,没办法像处理普通视频文件那样无缝循环,导致报错退出。
几个可行的解决办法
1. 用Shell脚本实现外部循环
这是最稳妥的办法,绕过ffmpeg本身的循环限制,用脚本反复调用ffmpeg命令:
while true; do # 执行推流命令 ffmpeg -fflags +igndts -hide_banner -re -i playlist_main2_c.m3u8 -c copy -f flv -flvflags no_duration_filesize rtmp:****** -loglevel verbose # 每次推流结束后,稍等几秒再重启,避免频繁重启 echo "推流中断,5秒后重新启动..." sleep 5 done
把这段代码存成loop_push.sh,给它加执行权限(chmod +x loop_push.sh),运行就可以实现无限循环推流了,哪怕某次推流意外结束,脚本都会自动重启。
2. 合并HLS分片为单个文件再循环
如果你的HLS分片是本地文件,先把所有TS文件合并成一个完整的视频,再用-stream_loop循环推流:
# 按顺序合并所有TS分片(确保文件名是按顺序命名的,比如xxx_001.ts、xxx_002.ts) cat playlist_main2_c_*.ts > merged_video.ts # 用合并后的文件循环推流 ffmpeg -stream_loop -1 -fflags +igndts -hide_banner -re -i merged_video.ts -c copy -f flv -flvflags no_duration_filesize rtmp:****** -loglevel verbose
这种方法适合静态HLS资源,能完美利用-stream_loop的原生循环功能,但如果是远程HLS流或者动态更新的分片,就不太适用了。
3. 修改HLS播放列表(仅限静态列表)
打开你的playlist_main2_c.m3u8文件,看看里面有没有#EXT-X-ENDLIST标签——这个标签是用来标记播放列表结束的。如果有的话,删掉它,然后再尝试用原来的命令推流,ffmpeg可能会尝试重新读取播放列表实现循环。不过这个方法只对静态的、不会更新的HLS列表有效,动态生成的列表大概率没用。
备注:内容来源于stack exchange,提问作者enriquedc04

