尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

FFmpeg HLS 从入门到能打:不只是 -hls_time 10那么简单

FFmpeg HLS 从入门到能打:不只是 -hls_time 10那么简单 目录一、先建立心智模型FFmpeg 眼里 HLS 是什么二、一条“能看”和一条“能上线”的命令差距有多大新手级只求能播工程级直播 / 点播通用模板三、HLS 切片最核心的 3 个参数1️. -hls_time≠ 精确时长90% 误解点2️. -hls_list_size直播 / 点播的分水岭3️. -hls_flagsFFmpeg HLS 的“灵魂开关”四、文件名 CDN 友好设计默认行为推荐五、直播 vs 点播两套完全不同的 m3u8 哲学直播 HLSRTMP → HLS点播 HLSVOD六、进阶FFmpeg 生成「多码率 Master Playlist」七、低延迟 HLSLL-HLS / Apple 新规范八、FFmpeg HLS 最常见的 5 个坑九、排查 HLS 的黄金三板斧十、总结觉得有用就请您帮忙点赞转发收藏吧您的鼓励是我创作的动力多谢看官。由于能力水平有限文中的错误或不严谨的地方在所难免还请批评指正。使用 FFmpeg 进行 HLSHTTP Live Streaming打包是将视频转换为自适应流媒体格式的核心操作主要生成 ‌.m3u8 播放列表‌和 ‌.ts 视频分片‌或 fMP4 分片。执行完成后目录中将生成.m3u8索引文件和若干.ts数据分片可直接部署到 Web 服务器或通过 CDN 分发。很多人对 FFmpeg HLS 的认知停留在三行命令ffmpeg -i src.mp4 -c copy -f hls output.m3u8结果延迟 30s、Safari 花屏、iOS 切不了码率、CDN 回源爆炸。真相是HLS 不是“输出格式”是切片 索引 生命周期管理FFmpeg 的 HLSmuxer 参数有 60 个90% 的人只用 2 个直播 / 点播 / 低延迟 HLSLHLS / LL-HLS完全不是同一套参数这篇不堆参数表按工程视角把 FFmpeg HLS 拆成 5 层讲清楚。一、先建立心智模型FFmpeg 眼里 HLS 是什么[ Input ] ↓ [ Demuxer ] → [ Decoder ] → [ Encoder ] → [ Muxer ] ↓ hls muxer不是 flv/mp4 ↓ ┌─────────────────────────────┴──────────────────────────────┐ │ts/mp4 segment (.ts/.m4s) playlist (.m3u8) 自动删除旧片 │ └─────────────────────────────┬──────────────────────────────┘ ↓ HTTP Server关键认知-f hls用的是hlsencHLS muxer真正写的是xx.ts/xx.m4s媒体切片index.m3u8播放列表HLS muxer 内部干三件事按时间 / GOP 切 segment维护 m3u8 条目数滚动窗口控制 segment 命名、加密、init 段MP4 是文件思维HLS 是窗口思维二、一条“能看”和一条“能上线”的命令差距有多大新手级只求能播ffmpeg -i in.mp4 -c copy -hls_time 10 -f hls out.m3u8问题切片不在关键帧 → ts 开头绿屏列表无限长 → 内存/磁盘涨ts 文件名随机 → CDN 缓存混乱iOS 起播慢工程级直播 / 点播通用模板ffmpeg -i in.mp4 \ -c:v libx264 -g 50 -keyint_min 50 -sc_threshold 0 \ -c:a aac -ar 48000 -b:a 128k \ -preset veryfast \ -hls_time 6 \ -hls_list_size 6 \ -hls_flags delete_segmentsomit_endlist \ -hls_segment_filename seg_%05d.ts \ -f hls index.m3u8这一条命令已经能进生产环境 80% 场景。三、HLS 切片最核心的 3 个参数1️.-hls_time≠ 精确时长90% 误解点-hls_time 6FFmpeg 不会硬切而是找到最近的IDR 帧keyframe​ 再切所以GOP 2s → 实际 segment ≈ 6 / 8 / 10sGOP 不固定 → ts 时长抖动严重正确姿势点播 / 直播通用-g 50 # fps25 → GOP2s -sc_threshold 0 # 关场景切换强制 keyframe结论hls_time是“建议值”GOP 才是“真实边界”2️.-hls_list_size直播 / 点播的分水岭场景参数直播-hls_list_size 5~8点播-hls_list_size 0全列表list_size5→ m3u8 永远只保留 5 个 segmenthlsenc 会自动删老 ts配合 hls_flags3️.-hls_flagsFFmpeg HLS 的“灵魂开关”高频组合-hls_flags delete_segmentsomit_endlistappend_listflag作用delete_segments自动删过期 ts防磁盘炸omit_endlist不写#EXT-X-ENDLIST→ 直播模式append_list复用旧 m3u8不重写 initdiscont_start推流重连后加 discontinuityprogram_date_time加 PDT利于日志对齐直播忘了 omit_endlist 播放器以为点播直接卡死四、文件名 CDN 友好设计默认行为index.m3u8 index0.ts index1.ts问题重推流 index0.ts 内容变了 → CDN 脏缓存推荐-hls_segment_filename hls/stream_%Y%m%d%H%M_%05d.ts或-hls_segment_filename seg_%09d.ts五、直播 vs 点播两套完全不同的 m3u8 哲学直播 HLSRTMP → HLSffmpeg -i rtmp://xxx/live \ -c:v libx264 -g 50 -preset veryfast \ -c:a aac \ -hls_time 4 \ -hls_list_size 5 \ -hls_flags delete_segmentsomit_endlist \ -f hls live.m3u8特征无 ENDLIST小窗口3~10 个 segment延迟 ≈ hls_time × list_size点播 HLSVOD-hls_list_size 0 -hls_flags independent_segments特征全列表可 seekts 名固定 → CDN 永久缓存六、进阶FFmpeg 生成「多码率 Master Playlist」很多人以为 FFmpeg 不能做 master.m3u8其实可以但有点拧巴ffmpeg -i in.mp4 \ -map 0:v -b:v:0 1000k -s:v:0 1280x720 -profile:v baseline \ -map 0:v -b:v:1 500k -s:v:1 854x480 \ -map 0:a -b:a:0 128k \ -var_stream_map v:0,a:0 v:1,a:0 \ -hls_time 6 \ -hls_segment_filename v%v/seg_%05d.ts \ -f hls hls/v%v/index.m3u8生成v0/index.m3u8 v1/index.m3u8再手写一个master.m3u8#EXTM3U #EXT-X-STREAM-INF:BANDWIDTH1100000,RESOLUTION1280x720 v0/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH600000,RESOLUTION854x480 v1/index.m3u8这是国内 CDN 多码率标准做法七、低延迟 HLSLL-HLS / Apple 新规范FFmpeg ≥ 4.4 开始能玩-hls_playlist_type event -hls_time 2 -hls_flags independent_segmentsomit_endlist -hls_segment_type fmp4要点segment fmp4不是 ts配合EXT-X-PART需要 ffmpeg 播放器双支持延迟可压到 3~6s别信 1s那是营销八、FFmpeg HLS 最常见的 5 个坑不指定 GOP → ts 首帧非 IDR → Safari 黑屏copy 视频流但源 GOP 不规则 → 切片时间乱飞直播写完 ENDLIST → H5 播放器直接停ts 名不变 → CDN 缓存旧片花屏Windows 下路径%d忘了转义九、排查 HLS 的黄金三板斧# 看 m3u8 是否合法 cat index.m3u8 # 看 ts 实际时长 ffprobe seg_00000.ts -show_frames -select_streams v # 看 keyframe 间隔 ffprobe in.mp4 -skip_frame nokey -show_frames十、总结FFmpeg 的 HLS 不是“一键输出”而是把编码节奏、GOP 设计、CDN 缓存、播放器行为​ 全绑在一起的系统问题。你调的不是-hls_time是观众手机里的起播速度和老板嘴里的延迟指标。
返回列表