FFmpeg 视频切片 m3u8 与合并 MP4 常用命令
wxk1991 Lv5

FFmpeg 视频切片 m3u8 与合并 MP4 常用命令

FFmpeg 做视频切片和合并非常方便。

常见场景:

  • MP4 切成 HLS
  • 生成 m3u8
  • 生成 .ts 分片
  • m3u8 合并回 MP4
  • 把多个 MP4 合并成一个

SQLite WAL 与 FFmpeg HLS 工作流


一、安装 FFmpeg

Ubuntu:

1
2
sudo apt update
sudo apt install -y ffmpeg

macOS:

1
brew install ffmpeg

查看版本:

1
ffmpeg -version

二、MP4 切片生成 m3u8

最常用命令:

1
2
3
4
5
6
7
8
9
10
mkdir -p hls

ffmpeg -y -hide_banner \
-i "input.mp4" \
-c:v libx264 \
-c:a aac \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_filename "hls/segment_%03d.ts" \
"hls/index.m3u8"

说明:

参数 作用
-hls_time 6 每个分片约 6 秒
-hls_playlist_type vod 点播列表
-hls_segment_filename 分片文件名
index.m3u8 播放列表

生成后目录类似:

1
2
3
4
5
hls/
├── index.m3u8
├── segment_000.ts
├── segment_001.ts
└── segment_002.ts

三、不转码快速切片

如果你的视频编码本身适合 HLS,可以尝试:

1
2
3
4
5
6
7
8
9
mkdir -p hls

ffmpeg -y -hide_banner \
-i "input.mp4" \
-c copy \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_filename "hls/segment_%03d.ts" \
"hls/index.m3u8"

优点:

1
速度快,几乎不损失画质。

缺点:

1
分片点受关键帧影响,不一定非常均匀。

如果需要更稳定的分片,建议转码并控制关键帧。


四、控制关键帧切片

例如每 6 秒一个分片:

1
2
3
4
5
6
7
8
9
10
11
mkdir -p hls

ffmpeg -y -hide_banner \
-i "input.mp4" \
-c:v libx264 \
-c:a aac \
-force_key_frames "expr:gte(t,n_forced*6)" \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_filename "hls/segment_%03d.ts" \
"hls/index.m3u8"

如果你发现切片时间不准,可以用这个版本。


五、生成 fMP4 HLS

传统 HLS 常用 .ts

现在也可以生成 fMP4 分片:

1
2
3
4
5
6
7
8
9
10
11
12
mkdir -p hls-fmp4

ffmpeg -y -hide_banner \
-i "input.mp4" \
-c:v libx264 \
-c:a aac \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_type fmp4 \
-hls_fmp4_init_filename "init.mp4" \
-hls_segment_filename "hls-fmp4/segment_%03d.m4s" \
"hls-fmp4/index.m3u8"

生成:

1
2
3
4
5
hls-fmp4/
├── index.m3u8
├── init.mp4
├── segment_000.m4s
└── segment_001.m4s

六、m3u8 合并回 MP4

本地 m3u8:

1
2
3
4
ffmpeg -y -hide_banner \
-i "hls/index.m3u8" \
-c copy \
"output.mp4"

如果是远程 m3u8:

1
2
3
4
5
ffmpeg -y -hide_banner \
-protocol_whitelist "file,http,https,tcp,tls,crypto" \
-i "https://example.com/video/index.m3u8" \
-c copy \
"output.mp4"

如果合并后音视频异常,可以尝试转码:

1
2
3
4
5
ffmpeg -y -hide_banner \
-i "hls/index.m3u8" \
-c:v libx264 \
-c:a aac \
"output.mp4"

七、多个 MP4 合并成一个 MP4

先创建 filelist.txt

1
2
3
file 'part1.mp4'
file 'part2.mp4'
file 'part3.mp4'

合并:

1
2
3
4
5
6
ffmpeg -y -hide_banner \
-f concat \
-safe 0 \
-i filelist.txt \
-c copy \
"merged.mp4"

如果编码参数不一致,使用转码:

1
2
3
4
5
6
7
ffmpeg -y -hide_banner \
-f concat \
-safe 0 \
-i filelist.txt \
-c:v libx264 \
-c:a aac \
"merged.mp4"

八、只切一段再生成 m3u8

比如只处理 00:01:00 到 00:03:00:

1
2
3
4
5
6
7
8
9
10
11
12
mkdir -p hls-clip

ffmpeg -y -hide_banner \
-ss 00:01:00 \
-to 00:03:00 \
-i "input.mp4" \
-c:v libx264 \
-c:a aac \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_filename "hls-clip/segment_%03d.ts" \
"hls-clip/index.m3u8"

九、常见问题

1. 合并 m3u8 报协议不允许

加:

1
-protocol_whitelist "file,http,https,tcp,tls,crypto"

2. 切片时间不均匀

原因通常是关键帧不在分片点。

使用:

1
-force_key_frames "expr:gte(t,n_forced*6)"

3. 合并 MP4 没声音

可能音频编码不兼容。

尝试:

1
-c:v copy -c:a aac

或者直接全转码:

1
-c:v libx264 -c:a aac

4. m3u8 里分片路径不对

检查:

1
-hls_segment_filename

如果要部署到网站,路径要和静态资源目录对应。


十、推荐命令总结

MP4 转 HLS:

1
ffmpeg -y -hide_banner -i "input.mp4" -c:v libx264 -c:a aac -hls_time 6 -hls_playlist_type vod -hls_segment_filename "hls/segment_%03d.ts" "hls/index.m3u8"

快速切片:

1
ffmpeg -y -hide_banner -i "input.mp4" -c copy -hls_time 6 -hls_playlist_type vod -hls_segment_filename "hls/segment_%03d.ts" "hls/index.m3u8"

m3u8 合并 MP4:

1
ffmpeg -y -hide_banner -i "hls/index.m3u8" -c copy "output.mp4"

多个 MP4 合并:

1
ffmpeg -y -hide_banner -f concat -safe 0 -i filelist.txt -c copy "merged.mp4"

总结

FFmpeg 处理 HLS 的核心就是三件事:

1
2
3
输入视频
生成 m3u8 和分片
必要时再合并回 MP4

如果只是快速切片,用:

1
-c copy

如果要兼容性和稳定性,用:

1
-c:v libx264 -c:a aac

如果切片不准,就控制关键帧。

这几组命令掌握后,绝大多数 m3u8 和 MP4 处理场景都够用了。