常用命令
1. 基础转换(格式、编码)
这是 FFmpeg 最基本的使用场景。
-
格式转码(如 MKV 转 MP4):
ffmpeg -i input.mkv output.mp4 -
指定编码器(如使用 H.264 和 AAC):
ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4 -
仅提取音频(无视频):
ffmpeg -i input.mp4 -vn -q:a 2 output.mp3
2. 视频剪辑与拼接
-
无损剪切(快速):
ffmpeg -ss 00:00:10 -to 00:00:30 -i input.mp4 -c copy output.mp4注意:
-c copy表示不重新编码,速度极快,但时间戳可能不够精确。 -
合并视频(文件列表法): 首先创建一个
filelist.txt,内容为: -
file 'part1.mp4' -
file 'part2.mp4' -
然后运行:
ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
3. 分辨率、码率与压缩
-
调整分辨率(缩放):
ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4 -
改变视频宽高比:
ffmpeg -i input.mp4 -aspect 16:9 output.mp4 -
压缩视频(通过恒定质量因子 CRF):
ffmpeg -i input.mp4 -vcodec libx264 -crf 23 output.mp4CRF 数值通常在 18-28 之间,数值越小质量越高,23 是默认平衡点。
4. 音频处理
-
静音(移除音轨):
ffmpeg -i input.mp4 -an output.mp4 -
调整音量:
ffmpeg -i input.mp3 -af "volume=1.5" output.mp3 -
音频采样率转换:
ffmpeg -i input.mp3 -ar 44100 output.mp3
5. 进阶技巧(GIF、水印、截图)
-
视频转 GIF:
ffmpeg -i input.mp4 -t 5 -pix_fmt rgb24 output.gif -
视频截图(截取第 5 秒的帧):
ffmpeg -i input.mp4 -ss 00:00:05 -frames:v 1 output.jpg -
添加文字水印:
ffmpeg -i input.mp4 -vf "drawtext=text='MyWatermark':x=10:y=10:fontsize=24:fontcolor=white" output.mp4
核心参数快速查阅表
| 参数 | 说明 |
|---|---|
-i |
输入文件路径 |
-c:v |
指定视频编码器(codec:video) |
-c:a |
指定音频编码器(codec:audio) |
-b:v |
设置视频码率(例如 2M) |
-r |
设置帧率(fps) |
-s |
设置分辨率(如 1920x1080) |
-vn / -an |
禁用视频 / 禁用音频 |
常用API
cpp
// 1. 分配一个封装上下文(AVFormatContext),它是 FFmpeg 的"总指挥部"
AVFormatContext* fmt_ctx = nullptr;
// 2. 打开视频文件(解析文件头,初始化 fmt_ctx)
// 返回 0 表示成功
if (avformat_open_input(&fmt_ctx, filename, nullptr, nullptr) < 0) {
std::cerr << "错误:无法打开文件 " << filename << std::endl;
return -1;
}
// 3. 读取流信息(探测内部的视频流、音频流参数)
if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {
std::cerr << "错误:无法获取流信息" << std::endl;
avformat_close_input(&fmt_ctx);
return -1;
}
找到流stream后,stream中包含codecpar,codecpar中的codec_type指明是音频流还是视频流
cpp
// 5. 遍历所有的"流",找到视频流并打印分辨率
for (unsigned int i = 0; i < fmt_ctx->nb_streams; i++) {
AVStream* stream = fmt_ctx->streams[i];
AVCodecParameters* codec_par = stream->codecpar;
// 判断是否为视频流
if (codec_par->codec_type == AVMEDIA_TYPE_VIDEO) {
std::cout << "--- 视频流 #" << i << " ---" << std::endl;
std::cout << "分辨率: " << codec_par->width << "x" << codec_par->height << std::endl;
// 打印编码格式名(如 h264, hevc)
const AVCodec* codec = avcodec_find_decoder(codec_par->codec_id);
if (codec) {
std::cout << "编码格式: " << codec->name << std::endl;
}
break; // 找到第一个视频流就退出循环
}
}