FFmpeg 是一个功能强大、开源的音视频处理工具,可以满足用户在音视频处理方面的各种需求。可以用于录制、转换、编辑、播放和流媒体处理等。它是一个跨平台的工具,支持 Windows、Mac、Linux 等操作系统。
FFmpeg 可以处理多种格式的音视频文件,包括常见的 AVI、MP4、MOV、FLV、WMV、MKV 等格式,以及音频格式如 MP3、WAV、AAC、FLAC 等。以下是一些它可以完成的任务:
- 转换音视频格式:可以将各种格式的音视频文件转换成所需的格式,例如将 MP4 文件转换为 AVI 文件。
- 剪辑和编辑视频:可以从视频文件中剪切出一段、拼接多段视频、添加字幕和水印等。
- 提取音频:可以从视频文件中提取出音频,将其保存成独立的音频文件。
- 视频截图:可以从视频文件中截取出一帧作为图片,用于制作视频预览图或者制作视频缩略图。
- 流媒体处理:可以使用 FFmpeg 构建流媒体服务器,对音视频进行实时编码和流式传输。
- 录制视频:可以使用 FFmpeg 进行屏幕录制,捕捉摄像头视频等。
本篇是一个简单的 Hello World 文档,主要记录下:
- 如何编译安装 FFmpeg
- 使用 FFmpeg获得视频信息
下面的例子使用的环境是:windows 11 + visual studio 2022
1. FFmpeg 安装
FFmpeg 安装有两种方式,一种是直接下载编译好的,另外一种就是自己下载源码自己编译。
1.1 自己编译
由于 FFmpeg 在 Unix/Linux 上编写时,使用了很多 Unix/Linux 系统上的库和工具,如 GCC、make、yasm、pkg-config 等,这些工具和库在 Windows 系统上并不存在,因此无法直接编译。为了能够去编译 FFmpeg,我们需要一个能在 windows 上运行的类 Unix/Linux 的环境。
MSYS2 就是一个在 Windows 操作系统上运行的类 Unix/Linux 的环境和开发工具和库,例如:当我们需要 gcc 时,可以直接在 MSYS2 环境里通过命令安装,实现在 Windows 平台上编译和运行开源软件。MSYS2 最终能够生成 Windows 平台上可执行的二进制文件。
首先从 www.msys2.org下载安装 MSYS2,或者从百度网盘:链接:https://pan.baidu.com/s/1leQZrvMcUHFI6Q3zEoAbLg,提取码:h57e
然后再 MSYS2 命令界面执行:
# 安装 gcc pacman -S --needed base-devel git mingw-w64-x86_64-toolchain # 安装汇编编译工具,这个是 FFmpeg 编译过程中需要的 pacman -S nasm yasm
接着从 Download FFmpeg下载 FFmpeg 源码,或者从百度网盘下载:链接:https://pan.baidu.com/s/1gSSAkFamNSgm6vToyQ4a2A 提取码:22di
然后 cd 到 FFmpeg 源码目录(注意:路径字符串放在双引号中),开始配置编译环境:
./configure --enable-shared --disable-static
然后开始编译 FFmpeg:
make
最后是安装软件,这一步就是将 FFmpeg 库、可执行文件、相关的头文件、配置文件拷贝到指定目录:
make install prefix="C:\Users\china\Downloads\ffmpeg-snapshot\ffmpeg\install"
最后将 bin 目录中的所有的 *.lib 文件都拷贝到 lib 目录下
1.2 直接下载
点击链接 Download FFmpeg 按照图上的标注下载即可,也可以直接从百度网盘下载:链接:https://pan.baidu.com/s/1_X_aBYj4tIKzFPBcmLi1SQ 提取码:e2cj
2. FFmpeg 示例
创建一个空项目,做如下配置:
- 将 bin 目录下的所有 dll 文件拷贝到项目目录下
- 配置头文件路径
- 配置库文件路径
示例代码为通过 FFmpeg 获得一个输入视频的相关信息:
#include <iostream> extern "C" { #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> } // 判断流的类型 void print_stream_type(AVStream * stream) { // 获得流的类型 AVMediaType type = stream->codecpar->codec_type; // 获得流的编码器参数,再获得编码类型 if (type == AVMEDIA_TYPE_VIDEO) { printf("视频流的类型: %s\n", av_get_media_type_string(type)); return; } if (type == AVMEDIA_TYPE_AUDIO) { printf("视频流的类型: %s\n", av_get_media_type_string(type)); return; } printf("未知类型"); } // 读取视频信息 void test() { AVFormatContext* av_format = nullptr; const char* url = "demo.mp4"; const AVInputFormat* fmt = nullptr; // 打开输入流,并读取头部信息 // av_format 用于获得读取到的视频信息, 内存由 avformat_open_input 函数分配 // url 读取的视频路径 // fmt 如果非空的话,这个参数将会强制设置输入流的格式。如果为空,则自动检测视频的格式 int ret = avformat_open_input(&av_format, url, fmt, nullptr); if (ret != 0) { av_log(nullptr, AV_LOG_INFO, "视频 %s 打开失败"); return; } // 视频封装格式 // mov,mp4,m4a,3gp,3g2,mj2 printf("视频封装格式: %s\n", av_format->iformat->name); // 输入视频时长 int64_t seconds = av_format->duration / AV_TIME_BASE; printf("输入视频时长: %lld 秒\n", seconds); // 视频流的数量 unsigned int number = av_format->nb_streams; printf("视频流的数量: %u\n", number); // 视频流的类型 print_stream_type(av_format->streams[0]); print_stream_type(av_format->streams[1]); // 输入视频帧率 AVRational frame_rate = av_format->streams[0]->avg_frame_rate; printf("输入视频帧率: %f fps\n", av_q2d(frame_rate)); // 视频编码类型 AVCodecID video_codec_type = av_format->streams[0]->codecpar->codec_id; // avcodec_get_name 函数根据编码类型ID返回编码类型名字 printf("视频编码类型: %s\n", avcodec_get_name(video_codec_type)); // 音频编码类型 AVCodecID audio_codec_type = av_format->streams[1]->codecpar->codec_id; printf("音频编码类型: %s\n", avcodec_get_name(audio_codec_type)); // 获得视频宽高 int w = av_format->streams[0]->codecpar->width; int h = av_format->streams[0]->codecpar->height; printf("视频分辨率为: %d %d\n", w, h); // 获得视频码率: 视频传输时平均比特数 // 比特率是指每秒传输的总比特数,包括视频和音频等其他数据所占用的比特数 int64_t brate = av_format->streams[0]->codecpar->bit_rate; printf("输入视频码率: %lld\n", brate); // 关闭输入流 avformat_close_input(&av_format); } int main() { test(); return 0; }
程序输出结果:
视频封装格式: mov,mp4,m4a,3gp,3g2,mj2 输入视频时长: 64 秒 视频流的数量: 2 视频流的类型: video 视频流的类型: audio 输入视频帧率: 59.990015 fps 视频编码类型: h264 音频编码类型: aac 视频分辨率为: 2560 1440 输入视频码率: 44186059