如何解决FFmpeg转推M3U8到RTMP时的跳段卡顿问题?
解决FFmpeg转推M3U8到RTMP时的片段过期卡顿问题
你遇到的Skipping 1 segments ahead, expired from playlists提示,本质是FFmpeg拉取M3U8时,本地缓存的片段已经被源服务器的播放列表标记为过期(HLS流的片段轮转机制会移除旧片段),而你的拉取/处理速度跟不上流的更新节奏,再加上命令里的无效参数拖慢了流程,最终导致播放卡顿延迟。
针对你的命令,直接按以下步骤调整:
1. 移除无效的HLS输出参数
你的输出格式是FLV(推RTMP),但命令里加了一堆针对HLS输出的参数:-segment_list_flags live -segment_list_size 300 -segment_time 300 -hls_list_size 300 -hls_time 300,这些参数完全没用,只会让FFmpeg做额外的无效处理,增加CPU和内存负担,必须删掉。
2. 优化输入流的缓冲与鲁棒性
- 增大
-thread_queue_size到32768,给输入流预留更大的缓冲队列,应对网络波动导致的拉取延迟,避免片段还没处理就过期。 - 添加
-fflags +discardcorrupt+igndts,自动跳过损坏的片段、忽略时间戳异常,减少因为流异常导致的停顿。 - 添加
-hls_flags +ignore_discont+delete_segments,忽略HLS流中不连续的片段,同时自动删除本地已过期的片段,避免缓存堆积拖慢处理速度。
3. 优化编码参数,降低CPU负载
- 如果转推的M3U8源音频已经是AAC格式且采样率为44100,直接用
-c:a copy代替-c:a aac,不用重新编码,节省大量CPU资源。 - 添加
-tune zerolatency,配合-preset superfast进一步优化H.264编码的低延迟特性,减少编码环节的延迟。
4. 检查循环参数的必要性
如果你的源是直播M3U8流,-stream_loop -1会导致流结束后循环拉取无效的过期片段,直接删掉这个参数;如果是点播M3U8循环播放,保留该参数即可,但要确保上述缓冲优化到位。
修改后的最终命令示例(针对直播流)
ffmpeg -thread_queue_size 32768 -fflags +discardcorrupt+igndts -hls_flags +ignore_discont+delete_segments -i http://demo.m3u8 -c:a copy -c:v h264 -vf scale=640:-1 -hide_banner -bf 0 -pix_fmt yuv420p -vprofile baseline -preset superfast -tune zerolatency -flvflags no_duration_filesize -f flv rtmp://myserver
如果源音频采样率不是44100,再把-c:a copy改回-c:a aac -ar 44100即可。
内容的提问来源于stack exchange,提问作者user2028856
相关产品推荐
相关产品推荐

