视频切片

视频切片
xu756视频切片
本文记录如何使用 FFmpeg 将 MP4 视频切片为 HLS 格式,适用于 Web 播放、点播视频分发、移动端播放等场景。
1. 目标
将一个输入视频:
1 | input.mp4 |
转换为 HLS 点播资源:
1 | index.m3u8 |
其中:
-
index.m3u8是 HLS 播放列表文件 -
init.mp4是 fMP4 初始化文件 -
seg_00000.m4s、seg_00001.m4s等是视频切片文件
最终可以通过支持 HLS 的播放器播放 index.m3u8。
2. FFmpeg 切片命令
1 | ffmpeg -y -i input.mp4 \ |
3. 参数说明
| 参数 | 说明 |
|---|---|
-y |
输出文件已存在时直接覆盖 |
-i input.mp4 |
指定输入视频文件 |
-map 0:v:0 |
选择第一个视频流 |
-map "0:a:0?" |
选择第一个音频流,? 表示没有音频时不报错 |
-r 30 |
输出帧率设置为 30 FPS |
-fps_mode cfr |
使用恒定帧率 CFR,便于切片和播放兼容 |
-c:v libx264 |
使用 H.264 编码 |
-preset veryfast |
编码速度预设,速度较快,压缩率适中 |
-crf 23 |
视频质量参数,数值越小质量越高、文件越大 |
-bf 0 |
禁用 B 帧,提升兼容性和降低播放延迟 |
-refs 1 |
设置参考帧数量为 1,提升兼容性 |
-g 180 |
GOP 长度为 180 帧 |
-keyint_min 180 |
最小关键帧间隔为 180 帧 |
-sc_threshold 0 |
禁用场景切换自动插入关键帧 |
-pix_fmt yuv420p |
使用兼容性最好的像素格式 |
-c:a aac |
音频编码为 AAC |
-b:a 128k |
音频码率为 128kbps |
-f hls |
输出格式为 HLS |
-hls_time 6 |
每个切片目标时长为 6 秒 |
-hls_playlist_type vod |
生成点播类型播放列表 |
-hls_flags independent_segments |
每个切片都是独立可解码片段 |
-hls_segment_type fmp4 |
使用 fragmented MP4 切片格式 |
-hls_fmp4_init_filename init.mp4 |
指定 fMP4 初始化文件名 |
-hls_segment_filename "seg_%05d.m4s" |
指定切片文件命名格式 |
index.m3u8 |
输出的 HLS 主播放列表 |
4. GOP 与切片时长的关系
当前命令中:
1 | -r 30 |
含义是:
1 | 30 FPS × 6 秒 = 180 帧 |
也就是说:
-
视频帧率为 30 FPS
-
每个 HLS 切片目标时长为 6 秒
-
每 180 帧插入一个关键帧
-
每个切片基本都从关键帧开始
这样可以保证切片边界稳定,播放器更容易从任意切片开始播放。
如果要改成 4 秒一个切片:
1 | 30 FPS × 4 秒 = 120 帧 |
对应参数应调整为:
1 | -r 30 |
如果要改成 10 秒一个切片:
1 | 30 FPS × 10 秒 = 300 帧 |
对应参数应调整为:
1 | -r 30 |
5. 输出目录示例
建议将输出文件放到单独目录中:
1 | mkdir -p output |
完整命令:
1 | ffmpeg -y -i input.mp4 \ |
输出结果:
1 | output/ |
注意:如果发现 init.mp4 没有生成在 output/ 目录,可以将参数改为:
1 | -hls_fmp4_init_filename "output/init.mp4" |
6. TS 切片版本
如果需要兼容更老的 HLS 播放器,可以使用 .ts 切片。
1 | ffmpeg -y -i input.mp4 \ |
fMP4 和 TS 的区别:
| 类型 | 后缀 | 特点 |
|---|---|---|
| fMP4 | .m4s |
更现代,适合新播放器和 DASH/HLS 统一分发 |
| TS | .ts |
兼容性更老、更广,但文件开销相对更大 |
7. 播放测试
可以使用 ffplay 测试:
1 | ffplay output/index.m3u8 |
也可以使用本地 HTTP 服务测试,避免浏览器直接打开文件时出现跨域或路径问题。
进入输出目录:
1 | cd output |
启动 HTTP 服务:
1 | python3 -m http.server 8080 |
访问:
1 | http://localhost:8080/index.m3u8 |
如果使用网页播放器,可以使用 hls.js 播放。
8. 常见问题
8.1 切片时长不是严格 6 秒
-hls_time 6 是目标切片时长,不一定绝对精确。HLS 通常会在关键帧处切片。
为了让切片接近 6 秒,需要保证:
1 | -g = fps × hls_time |
例如:
1 | -r 30 |
8.2 视频没有声音也能处理吗?
可以。
命令中:
1 | -map "0:a:0?" |
末尾的 ? 表示音频流可选。如果输入视频没有音频,不会导致命令失败。
8.3 为什么使用 yuv420p?
1 | -pix_fmt yuv420p |
是为了提高播放器兼容性,尤其是浏览器、移动端和部分硬件播放器。
8.4 为什么禁用 B 帧?
1 | -bf 0 |
禁用 B 帧可以:
-
降低解码复杂度
-
提升部分播放器兼容性
-
减少低延迟播放时的问题
但代价是压缩效率可能略低。
8.5 CRF 应该怎么选?
| CRF | 质量 | 文件大小 |
|---|---|---|
| 18 | 很高 | 较大 |
| 20 | 高 | 偏大 |
| 23 | 默认常用 | 适中 |
| 26 | 较低 | 较小 |
| 28 | 更低 | 很小 |
常用建议:
-
高质量归档:
-crf 18 -
普通点播:
-crf 22~24 -
节省带宽:
-crf 26~28
9. 推荐脚本
可以保存为:
1 | slice_hls.sh |
脚本内容:
1 |
|
添加执行权限:
1 | chmod +x slice_hls.sh |
使用方式:
1 | ./slice_hls.sh input.mp4 output 30 6 |
参数含义:
1 | ./slice_hls.sh 输入文件 输出目录 帧率 切片时长 |
10. 总结
使用 FFmpeg 生成 HLS 视频切片的关键点:
-
使用
-f hls输出 HLS -
使用
-hls_time控制切片目标时长 -
使用
-g和-keyint_min控制关键帧间隔 -
推荐让 GOP 等于
FPS × 切片秒数 -
使用
-hls_playlist_type vod生成点播列表 -
使用
-hls_segment_type fmp4生成.m4s切片 -
如果需要老播放器兼容,可以改用
.ts切片
当前推荐命令适合生成标准的 HLS 点播资源:
1 | ffmpeg -y -i input.mp4 \ |







