常用音视频编码器
| 类型 | 文件格式 | 编码器名称 | FFmpeg 参数 | 备注 |
|---|---|---|---|---|
| 音频 | WAV | PCM 16-bit Little Endian | -c:a pcm_s16le | 无损格式,常用于 WAV 文件,pcm_s16le 表示 16 位小端编码。 |
| MP3 | LAME MP3 | -c:a libmp3lame | 有损压缩,需指定 libmp3lame 编码器。 | |
| AAC | Advanced Audio Coding | -c:a aac | 高效有损编码,适用于流媒体和移动设备。 | |
| FLAC | Free Lossless Audio | -c:a flac | 无损压缩,适合高保真音频存储。 | |
| Opus | Opus Interactive | -c:a libopus | 低延迟高音质,常用于实时通信和 Web 流媒体。 | |
| - | - | - | - | - |
| 视频 | MP4 | H.264/AVC | -c:v libx264 | 广泛兼容的编码格式,适用于 MP4 和流媒体。 |
| MP4/HEVC | H.265/HEVC | -c:v libx265 | 更高压缩效率,适合 4K/8K 视频。 | |
| WebM | VP9 | -c:v libvpx-vp9 | 开源编码器,支持 WebM 格式,常用于 Web 端。 | |
| WebM/AV1 | AV1 | -c:v libaom-av1 | 开源编码器,支持 WebM 格式,常用于 Web 端。 | |
| MKV | VP8 | -c:v libvpx | 较旧的 WebM 编码器,兼容性较好。 |
视频
无损截取
要实现音频无损时间截取并且音视频都不重新编码,可以使用 FFmpeg 的 -c copy 选项进行直接流复制,同时使用 -ss 和 -to 参数来指定截取的时间段。
命令格式
ffmpeg -ss [开始时间] -to [结束时间] -i input_file -c copy output_file
参数解释:
-ss [开始时间]:指定开始时间,可以精确到毫秒(hh:mm:ss.sss)。-to [结束时间]:指定结束时间,同样可以精确到毫秒(hh:mm:ss.sss)。- 精确时间点:
-ss和-to支持毫秒级的时间点(hh:mm:ss.sss),你可以精确控制截取的开始和结束位置。
- 精确时间点:
-c copy:表示音频和视频都不重新编码,直接复制原始流。input_file:输入文件(比如 MP4、MKV 等)。output_file:输出文件的名称和格式。
注意事项:
时间精度:当
-ss放在-i之前时,FFmpeg 会在时间上快速跳转,但精度可能不如将-ss放在-i之后。因此,如果你需要非常精确的截取时间,建议将-ss放在-i之后。快速跳转,时间可能不够精确:
ffmpeg -ss 00:01:30 -i input.mp4 -to 00:02:30 -c copy output.mp4精确跳转,处理速度略慢:
ffmpeg -i input.mp4 -ss 00:01:30 -to 00:02:30 -c copy output.mp4
格式兼容性:确保输出文件格式与输入文件格式兼容。例如,如果输入文件是 MP4,输出文件最好也是 MP4,以确保容器支持音视频流格式。
视频转gif
下面是使用 FFmpeg 将视频转为 GIF 文件的方法,以及如何从视频中提取 精确时间区间 转换为 GIF。
ffmpeg -i input.mp4 -vf "fps=24,scale=640:-1:flags=lanczos" output.gif
参数说明:
-i input.mp4:输入视频文件。-vf:视频滤镜,用于指定帧率和缩放。fps=10:指定 GIF 的帧率为 10(可以根据需要调整)。scale=640:-1:指定 GIF 的宽度为 640 像素,高度按比例调整(-1表示自动计算高度以保持比例)。flags=lanczos:使用高质量的缩放算法。
output.gif:输出 GIF 文件的路径。
- 转换指定时间区间为 GIF
如果您只想从视频的某个时间段提取 GIF,使用以下命令:
ffmpeg -ss 00:00:05 -to 00:00:10 -i input.mp4 -vf "fps=10,scale=640:-1:flags=lanczos" output.gif
参数说明:
-ss 00:00:05:指定开始时间(例如 5 秒)。-to 00:00:10:指定结束时间(例如 10 秒)。- 其他参数与上述解释相同。
更高质量的 GIF 输出(一步到位)
ffmpeg -i input.mp4 ^
-vf "fps=10,scale=640:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=64[p];[s1][p]paletteuse=dither=none" ^
-loop 0 output.gif
提示
- 如果使用
bash把换行符换成\ - 这条命令也可以压缩已经存在的gif文件,只要把
.mp4换成.gif就行了
关键参数说明
基本结构
ffmpeg -i input.mp4 -vf "复杂的滤镜链" -loop 0 output.gif
-i input.mp4
- 作用:指定输入文件
- 说明:
-i是 input 的缩写,后面接输入视频文件路径
-vf "xxx"
- 作用:滤镜链
- 说明:
-vf是 video filter 的缩写,后面接一系列视频滤镜操作
重要
滤镜链分解:
fps=10,scale=640:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=64[p];[s1][p]paletteuse=dither=none
按分号 ; 分割为三个主要阶段:
阶段一:视频预处理
fps=10,scale=640:-1:flags=lanczos,split[s0][s1]
fps=10- 设置输出帧率为 10 帧/秒
- 原视频可能是 30fps,这样减少 2/3 的帧数,大幅减小体积
scale=640:-1:flags=lanczos640:-1:宽度固定为 640 像素,高度按比例自动计算(-1表示自动)flags=lanczos:使用 lanczos 缩放算法,保持较好的清晰度
split[s0][s1]- 将处理后的视频流复制为两个相同的流:
[s0]和[s1] - 目的是一个流用于生成调色板,另一个用于最终输出
- 将处理后的视频流复制为两个相同的流:
阶段二:生成调色板
[s0]palettegen=max_colors=64[p]
[s0]:引用前面 split 创建的第一个视频流palettegen:调色板生成器max_colors=64:限制调色板最多使用 64 种颜色(默认256)[p]:将生成的调色板命名为[p],供后续使用
阶段三:应用调色板
[s1][p]paletteuse=dither=none
[s1]:引用 split 创建的第二个视频流[p]:引用前面生成的调色板paletteuse:将调色板应用到视频流dither=none:关闭颜色抖动,保持文字边缘清晰(但可能产生颜色色块)
-loop 0
- 作用:设置 GIF 循环播放
- 说明:
0表示无限循环,-1表示不循环,正数表示循环次数
output.gif
- 作用:指定输出文件名
整个流程总结
- 输入视频 → 降帧到
10fps→ 缩放到640px宽 - 分流:一路生成
64色调色板,另一路保留视频内容 - 合并:将调色板应用到视频流,关闭抖动
- 输出:生成无限循环的 GIF 文件
这样在保证文字可读的前提下,通过降低帧率、分辨率和颜色数来最大化压缩。
进一步优化选项
如果体积仍然太大:
- 降低分辨率(如
scale=480:-1) - 减少帧率到
fps=6 - 颜色数减到
max_colors=32
- 降低分辨率(如
如果文字模糊:
- 保持分辨率不低于原视频的 1/3
- 调高
max_colors=128保留更多颜色细节
更高质量的 GIF 输出(两步)
为了生成高质量的 GIF,可以使用以下方法:
第一步:将视频转换为调色板(提高颜色表现力)
ffmpeg -ss 00:00:05 -to 00:00:10 -i input.mp4 -vf "fps=10,scale=640:-1:flags=lanczos,palettegen" palette.png
第二步:使用调色板生成 GIF
ffmpeg -ss 00:00:05 -to 00:00:10 -i input.mp4 -i palette.png -lavfi "fps=10,scale=640:-1:flags=lanczos [x]; [x][1:v] paletteuse" output.gif
为什么需要调色板?
GIF 文件支持的颜色数量有限(最多 256 种颜色),直接生成 GIF 可能会导致颜色失真。通过生成调色板并在生成 GIF 时使用调色板,可以改善颜色效果。
示例场景
示例 1:从第 10 秒到第 15 秒提取 GIF,宽度为 480 像素
ffmpeg -ss 00:00:10 -to 00:00:15 -i input.mp4 -vf "fps=10,scale=480:-1:flags=lanczos" output.gif
示例 2:从视频中生成高质量的短 GIF
# 第一步:生成调色板
ffmpeg -ss 00:00:10 -to 00:00:15 -i input.mp4 -vf "fps=15,scale=480:-1:flags=lanczos,palettegen" palette.png
## 第二步:使用调色板生成 GIF
ffmpeg -ss 00:00:10 -to 00:00:15 -i input.mp4 -i palette.png -lavfi "fps=15,scale=480:-1:flags=lanczos[x]; [x][1:v] paletteuse" high_quality.gif
## 或第二步:DeepSeek给的
ffmpeg -ss 00:00:10 -to 00:00:15 -i input.mp4 -i palette.png -filter_complex "fps=15,scale=640:-1:flags=lanczos[x];[x][1:v]paletteuse=dither=sierra2_4a" -loop 0 output_high.gif
## 如果视频帧率不是整数30或者60,那么gif设置整数30或60会出现慢放的问题,则可以给类似59.9fps的视频生成fps30的gif,然后使用速度补偿机制
## setpts=0.5*PTS:速度补偿核心(0.5=60/30,保持原速播放)
ffmpeg -ss 00:00:10 -to 00:00:15 -i input.mp4 -i palette.png -filter_complex "fps=15,scale=640:-1:flags=lanczos,setpts=0.5*PTS[x];[x][1:v]paletteuse=dither=sierra2_4a" -loop 0 output_high.gif
提取音频流
要从一个 MP4 文件中无损地提取 AAC 音频流,而不进行重新编码,你可以使用 FFmpeg 的 -c copy 选项,它可以直接复制音频流而不改变其编码格式。以下是详细的步骤和命令:
提取音频流的命令
ffmpeg -i input.mp4 -vn -acodec copy output.aac
最好使用这个,因为上面的aac只是原始音频流可能在某些软件内不能正确识别出 duration 数据
ffmpeg -i input.mp4 -vn -acodec copy output.m4a
解释每个参数的作用
-i input.mp4:指定输入文件(这里是input.mp4)。-vn:表示不处理视频流(即忽略视频流,只提取音频)。-acodec copy:直接复制音频流,不进行重新编码。-c:a copy:现在推荐这种写法。属于 FFmpeg 的新语法规范,采用-c:流类型的格式(如-c:v表示视频流,-c:a表示音频流)。这种格式更清晰,支持多流类型独立控制,例如同时指定视频和音频编解码器时更灵活。
output.aac:指定输出文件的名称和格式(这里为output.aac)。
这个命令将 MP4 文件中的 AAC 音频流无损地提取为一个 .aac 文件。由于没有进行重新编码,提取过程非常快速,并且不会导致音质损失。
注意事项
文件格式:提取出来的音频流通常会使用
.aac扩展名,因为原始音频流是 AAC 编码。如果你需要将其封装到其他容器格式中(如 MP3 或 WAV),则可能需要重新编码或使用不同的容器格式。音频流的选择:如果 MP4 文件中有多个音频流,你可以使用
-map选项指定要提取的流。例如,如果你只想提取第二个音频流,你可以使用:ffmpeg -i input.mp4 -map 0:a:1 -acodec copy output.aac其中,
-map 0:a:1指的是选择第一个文件(0:)的第二个音频流(a:1)。
指定时间段
ffmpeg -ss 00:01:00 -to 00:02:00 -i input.mp4 -vn -acodec copy output.aac
解释每个参数的作用
-ss 00:01:00:指定开始时间,这里表示从视频的第1分钟开始。支持毫秒,格式:hh:mm:ss.sss-to 00:02:00:指定结束时间,这里表示到视频的第2分钟结束。支持毫秒,格式:hh:mm:ss.sss
wav
无损截取 WAV 文件,并保证格式为 PCM,FFmpeg 无法完全使用 -c copy,因为 WAV 文件中的音频流通常需要是 PCM 格式。但是你可以通过指定 -c:a pcm_s16le 来确保 WAV 格式,并且使用 -ss 和 -to 来定义时间段。
命令示例
ffmpeg -ss 00:01:00 -to 00:02:00 -i input.wav -c:a pcm_s16le output.wav
参数解释
-ss 00:01:00:指定开始时间,表示从音频的1分0秒处开始。-to 00:02:00:指定结束时间,表示到音频的2分0秒处结束。-i input.wav:指定输入文件,格式为 WAV。-c:a pcm_s16le:指定音频编解码器为 PCM 16位小端(WAV 格式的标准编码)。output.wav:输出的 WAV 文件。
解释
由于 WAV 文件通常是未压缩的 PCM 数据流,你可以将音频从指定的时间范围内提取出来,且音频不会进行压缩或重新编码。不过,音频仍需要明确设置为 PCM 格式,因为 WAV 文件要求特定的音频格式。
处理音频流
指定时间段
ffmpeg -ss 00:01:00 -to 00:02:00 -i input.mp3 -c copy output.mp3
-c copy 表示所有流都使用原始流(即复制流,不进行重新编码)
-c:v libx264 表示视频流使用 libx264 编解码器,-c:a aac 表示音频流使用 aac 编解码器。
-acodec copy:音频流使用原始编码,不重新编码。
倍速
使用 atempo 滤镜。注意,atempo 只支持在 0.5x 到 2.0x 之间的速度调整。如果需要更高或更低的倍速,可以链式使用多个 atempo。
如果你需要调整到其他倍速,比如 1.5x,可以使用:
ffmpeg -i input.wav -filter:a "atempo=1.5" output.wav
如果要处理超过 2.0x 或低于 0.5x 的速度,比如 4.0x,可以这样写:
ffmpeg -i input.wav -filter:a "atempo=2.0,atempo=2.0" output.wav
调整音量
在 FFmpeg 中调整音频文件的音量倍率,可以通过 volume 音频滤镜实现。以下是具体方法和注意事项:
基本音量倍率调整
命令格式:
ffmpeg -i input.wav -af "volume=2.0" output.wavvolume=2.0表示将音量放大至原始音量的 2 倍(线性增益)。- 若需缩小音量,可设为
0.5(即原始音量的 50%)。
注意事项:
直接使用倍数可能导致削波(超过最大振幅值),建议结合eval=frame参数优化动态处理:ffmpeg -i input.wav -af "volume=2.0:eval=frame" output.wav
2. 使用分贝(dB)单位调整
- 若需以分贝为单位调整,可在数值后加
dB:ffmpeg -i input.wav -af "volume=3dB" output.wav3dB表示音量增加约 1.23 倍(分贝与线性增益的换算公式为10^(dB/20))。- 负值表示降低音量,如
-6dB为原始音量的 50%。
防止削波的进阶参数
- 启用
precision参数提高计算精度,减少失真:ffmpeg -i input.wav -af "volume=2.0:precision=fixed" output.wav - 使用
limiter滤镜限制峰值(推荐组合使用):ffmpeg -i input.wav -af "volume=2.0,limiter=1" output.wavlimiter=1将峰值限制在 0dBFS(最大振幅值)。
- 启用
保留元数据与编码格式
- 若需保留原始文件的元数据,添加
-map_metadata 0:ffmpeg -i input.wav -af "volume=2.0" -map_metadata 0 output.wav - 指定编码格式(如 PCM 16-bit):
ffmpeg -i input.wav -af "volume=2.0" -acodec pcm_s16le output.wav
- 若需保留原始文件的元数据,添加
验证与调试
- 使用
astats滤镜分析输出音量:ffmpeg -i output.wav -af "astats=metadata=1:reset=1" -f null - - 逐步调整倍率,避免过度放大导致失真。
- 使用
总结
通过 volume 滤镜可灵活控制音量倍率,结合分贝单位、削波保护和编码参数,能实现高质量的音频增益。建议优先使用分贝单位调整(如 6dB),并启用 limiter 防止削波。
不规范的mp3
重新编码
mp3
ffmpeg -i input.mp3 -c:a libmp3lame -qscale:a 2 output_fixed.mp3
ffmpeg -i 七重人格(2023火星演唱会现场版)-华晨宇.mp3 -c:a libmp3lame -b:a 320k -ac 2 ../output/七重人格(2023火星演唱会现场版)-华晨宇.mp3
flac
# 先使用ffprobe查看原始码率、频率、位深度之后
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '温暖的房子(合唱)-tascam x6.flac':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41iso5
encoder : Lavf59.27.100
description : Bilibili XCoder v2.0.2
Duration: 00:06:20.50, start: 0.000000, bitrate: 1522 kb/s
Stream #0:0[0x1](und): Audio: flac (fLaC / 0x43614C66), 48000 Hz, stereo, s32 (24 bit), 17 kb/s (default)
Metadata:
handler_name : Bento4 Sound Handler
vendor_id : [0][0][0][0]
# 修复命令
ffmpeg -i "温暖的房子(合唱).flac" -c:a flac -sample_fmt s32 -ar 48000 -ac 2 -compression_level 8 -map_metadata 0 "温暖的房子(合唱)_fixed.flac"
# ffprobe 验证
Input #0, flac, from '温暖的房子(合唱)_fixed.flac':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41iso5
comment : Bilibili XCoder v2.0.2
encoder : Lavf61.1.100
Duration: 00:06:20.50, start: 0.000000, bitrate: 1524 kb/s
Stream #0:0: Audio: flac, 48000 Hz, stereo, s32 (24 bit)
参数详解:
- 编码控制
-c:a flac:强制使用FLAC编码器重新封装,修复损坏的容器结构 - 位深度保留
-sample_fmt s32:保持原始24bit音频(s32表示32位容器存储24位数据) - 采样率/声道同步
-ar 48000 -ac 2:锁定48kHz采样率和立体声输出,避免自动转换 - 元数据保护
-map_metadata 0:完整复制原始元数据(如专辑/艺术家信息) - 优化建议
-compression_level 8:使用FLAC最高压缩等级(0-12范围),在保持无损前提下减小文件体积
mp3 -> aac
ffmpeg -i input.mp3 -c:a aac -q:a 2 output.aac
-c:aaac指定音频编码器为 AAC
-ar 44100设置采样率为 44.1kHz
-ac 2设置音频为立体声
-b:a 128k和下方二选一设置 AAC 输出文件的音频码率为 128 kbps。
-q:a和上方二选一自动匹配原始码率
