FFmpeg使用指南

命令行参数

基础参数

  • -a/vn: 去掉音频或视频
  • -a/vcodec: 指定音视频编码器
    • copy: 不重新编码
    • 可指定为h264或aac等

常用命令

1. 获取视频信息

1
ffmpeg -i video.avi

2. 音视频流处理

1
2
3
4
5
6
7
8
# 去掉视频流
ffmpeg -i input.mp4 -an -vcodec copy output.mp4

# 音频重编码为AAC
ffmpeg -i input.mp4 -acodec aac output.mp4

# 转换为WAV格式
ffmpeg -i input.mp4 -acodec pcm_s16le output.wav

3. 视频截图

1
ffmpeg -i test.mp4 -ss 10 -frames:v 1 -s 1920x1080 output.jpg

参数说明:

  • -ss <时间>: 指定起始时间
  • -s <宽度x高度>: 调整图片大小
  • -frames:v 1: 只截取一帧

4. 添加水印

1
2
# 图片水印
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=10:10" output.mp4

位置参数:

  • 左上角: overlay=10:10
  • 右上角: overlay=W-w-10:10
  • 左下角: overlay=10:H-h-10
  • 右下角: overlay=W-w-10:H-h-10

其中:

  • W: 视频宽度
  • H: 视频高度
  • w: 水印宽度
  • h: 水印高度
1
2
3
4
5
# 文字水印
ffmpeg -i input.flv -vf "drawtext=fontfile=simhei.ttf: text='抖音':x=100:y=10:fontsize=24:fontcolor=yellow:shadowy=2" drawtext.mp4

# GIF水印
ffmpeg -y -i test2.mp4 -ignore_loop 0 -i test.gif -filter_complex overlay=0:H-h test_out2.mp4

5. 视频旋转

1
ffmpeg -i test.mp4 -vf "transpose=1" out.mp4  # 顺时针旋转90°

API使用

视频播放流程

1. 格式上下文(AVFormatContext)

1
2
3
4
5
6
7
8
9
10
11
12
13
AVFormatContext *pFormatCtx;
pFormatCtx = avformat_alloc_context(); // 分配格式上下文
avformat_open_input(&pFormatCtx, filePath.toUtf8().constData(), 0, 0); // 初始化上下文
avformat_find_stream_info(pFormatCtx, NULL); // 获取流信息

// 查找视频流索引
for (i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
streamIndex = i;
isVideo = 0;
break;
}
}

2. 解码器设置

1
2
3
4
5
6
7
AVCodecContext *pAVctx;  // 解码器上下文
AVCodec *pCodec; // 实际解码器

pAVctx = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(pAVctx, pFormatCtx->streams[streamIndex]->codecpar);
pCodec = avcodec_find_decoder(pAVctx->codec_id);
avcodec_open2(pAVctx, pCodec, NULL);

3. 数据包和帧处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
AVPacket *pAVpkt = av_packet_alloc();
AVFrame *pAVframe = av_frame_alloc();
AVFrame *pAVframeRGB = av_frame_alloc();

// 图像转换上下文
SwsContext *pSwsCtx = sws_getContext(...);

// 解码循环
while(av_read_frame(pFormatCtx, pAVpkt) >= 0) {
avcodec_send_packet(pAVctx, pAVpkt);
avcodec_receive_frame(pAVctx, pAVframe);
sws_scale(...); // 图像转换
// 显示到窗口
}

音频录制流程

1
2
3
4
5
6
7
8
9
10
11
12
// 初始化
avdevice_register_all();
const AVInputFormat *fmt = av_find_input_format(FMT_NAME);
avformat_open_input(...); // 打开麦克风

// 录制循环
while(...) {
av_read_frame(ctx, &pkt); // 读取PCM数据
}

// 结束处理
writeWavHeader(outputFile, 44100, 2, 16); // 更新WAV头部