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
- FFmpeg 安装 {#title-0} =======================
FFmpeg 安装有两种方式,一种是直接下载编译好的,另外一种就是自己下载源码自己编译。
1.1 自己编译 {#title-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 直接下载 {#title-2}
点击链接 Download FFmpeg 按照图上的标注下载即可,也可以直接从百度网盘下载:链接:https://pan.baidu.com/s/1_X_aBYj4tIKzFPBcmLi1SQ 提取码:e2cj
- FFmpeg 示例 {#title-3} =======================
创建一个空项目,做如下配置:
- 将 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