FFmpeg生成HLS分段时在约5300段后停止分段的问题求助
我之前处理过类似的长时间HLS流录制故障,结合你的脚本和现象来看,问题大概率出在FFmpeg旧版本的segment模块bug、时间戳混乱,或者分段列表的隐性限制上。下面是一步步的排查和解决思路:
1. 优先排查FFmpeg版本问题
你提到需要1.0.5以上版本,但早期FFmpeg的segment模块在处理超长时间(比如24小时)的流时,存在计数器溢出或者内存泄漏的问题,导致到一定分段数后停止创建新文件。建议你升级到FFmpeg 4.x或5.x的稳定版,新版本的segment和hls模块修复了大量长时间运行的bug。
2. 替换segment模块为原生HLS封装
你现在用的是-f segment生成m3u8,其实FFmpeg有专门的-f hls封装,对HLS流场景的支持更完善,尤其是长时间录制的稳定性。修改后的FFmpeg命令如下:
ffmpeg -y -r 15 -i live.h264 -f alsa -i default:CARD=C525 -r:a 48000 -ac 1 -af adelay=32s -c:v copy -c:a aac -b:a 128k -map 0:0 -map 1:0 \ -f hls \ -hls_time 7 \ -hls_list_size 0 \ -hls_flags append_list \ -hls_segment_filename /var/www/html/ppc/saves/live/%08d.ts \ /var/www/html/ppc/saves/live/live.m3u8 < /dev/null
关键参数说明:
-hls_list_size 0:关闭分段列表的长度限制,默认会只保留最近的几个分段,设置0后会保留所有分段(满足你1天回放的需求)-hls_flags append_list:实时追加新分段到m3u8列表,确保播放端能获取到最新流- 去掉了
-r 30:强制修改帧率会导致时间戳混乱,输入是15fps就保持原帧率即可,HLS可以兼容不同帧率的流
3. 修复时间戳漂移问题
raspivid输出的H.264流可能存在时间戳不连续的情况,长时间运行后累积误差会导致FFmpeg无法正确计算分段时间。可以添加以下参数让FFmpeg使用壁钟时间作为时间戳:
-use_wallclock_as_timestamps 1 -fflags +genpts
把这两个参数加到FFmpeg的输入部分(比如-i live.h264之前),确保时间戳不会随运行时长漂移。
4. 排查psips工具的影响
psips用于给H.264流插入PS/SI信息,但某些版本的psips可能会破坏时间戳。可以暂时去掉psips,直接让raspivid输出到fifo:
raspivid -a 1036 -w 1640 -h 1232 -fps 15 -t 37200000 -b 1500000 -o live.h264 &
如果去掉后分段正常,那就是psips的问题,可以尝试升级psips或者换用FFmpeg的-bsf:v h264_mp4toannexb滤镜来替换psips的功能(把H.264的Annex B格式转换为适合MPEG-TS的格式)。
5. 用debug日志定位深层问题
如果以上方法还没解决,建议开启FFmpeg的debug日志,查看分段停止时的具体报错:
ffmpeg -y -r 15 -i live.h264 -f alsa -i default:CARD=C525 -r:a 48000 -ac 1 -af adelay=32s -c:v copy -c:a aac -b:a 128k -map 0:0 -map 1:0 \ -f hls \ -hls_time 7 \ -hls_list_size 0 \ -hls_flags append_list \ -hls_segment_filename /var/www/html/ppc/saves/live/%08d.ts \ -v debug > /var/log/ffmpeg_hls.log 2>&1 \ /var/www/html/ppc/saves/live/live.m3u8 < /dev/null
当分段停止时,查看/var/log/ffmpeg_hls.log,如果有“无法打开输出文件”“时间戳溢出”之类的错误,就能精准定位问题。
最后确认目录权限
虽然你说存储空间充足,但还是要确认FFmpeg运行的用户对/var/www/html/ppc/saves/live/目录有写入权限,避免因为权限问题无法创建新文件。
内容的提问来源于stack exchange,提问作者Hug Duino

