VS2022配置FFMPEG库基础教程
1 简介

1.1 起源与发展历程
FFmpeg诞生于2000年,由法国工程师Fabrice Bellard主导开发,其名称源自"Fast Forward MPEG",初期定位为多媒体编解码工具。2004年后由Michael Niedermayer接任维护,逐步发展成为包含音视频采集、格式转换、流媒体处理等完整功能的开源项目。经过25年迭代,当前最新7.x版本已支持H.266/VVC、AV1等新一代编码标准,在全球开发者社区贡献下形成包含7大核心库的生态系统。
1.2 核心功能与架构组成
该工具链以libavcodec编解码库为核心,涵盖libavformat(封装格式处理)、libswscale(图像缩放、颜色空间转化等)、libavfilter(滤镜系统)等模块,支持200+种媒体格式的相互转化。其命令行工具集可执行视频剪辑、帧率调整、硬件加速转码等操作,广泛应用于直播推流、视频会议、智能安防等领域。通过LGPL/GPL协议保障开源生态,已成为VLC、Blender等知名软件的基础依赖组件。
2 下载
为了避免复杂的编译过程,达到快速上手使用的目的,我们推荐使用官方预编译包。下载地址:官网


注意,一定选择含share字符的编译包。
3 VS2022开发FFMPEG的环境配置
FFMPEG作为一个标准的第三方库,其配置思路是与OpenCV、OpenVINO等是一样的。在工程里面,配置好头文件路径、库文件路径和名称以及二进制文件的路径。下面,我实际演示下如何一步步进行配置。
3.1 解压安装包
将下载的压缩包,解压至无中文路径的目录中,我把它解压在D:/Tool目录下。

可以大致看下,FFMPEG的目录结构:
- bin:二进制文件目录。
- doc:使用帮助文档。
- include:头文件。
- lib:库文件。
- presets:一些标准分辨率的vpx的预设文件。
3.2 新建工程
使用VS2022新建控制台工程,空项目即可。

3.3 配置头文件
右键项目 →属性→VC++ 目录,包含目录增加D:\Tool\ffmpeg-7.1-full_build-shared\include。

3.4 配置库文件
右键项目 →属性→VC++ 目录,库目录增加D:\Tool\ffmpeg-7.1-full_build-shared\lib。

配置库名称:

3.5 配置二进制文件
建议直接使用环境变量进行配置,方便省事。

3.6 环境测试
#include <iostream>
extern "C" {
#include <libavcodec/avcodec.h>
}int main() {std::cout << "FFmpeg版本: " << avcodec_version() << std::endl;return 0;
}
4、读取mp4文件,opencv显示。
为验证FFMPEG的环境是否彻底安装完成,我们采用一个小的例子程序,进行验证。读取一个mp4文件,使用FFMPEG进行格式解析,并转为RGB格式,使用opencv进行显示。
#include <iostream>
#include <opencv2/opencv.hpp>extern "C" {
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}int main() {// FFmpeg初始化avformat_network_init();AVFormatContext* fmt_ctx = nullptr;// 打开媒体文件(替换为你的MP4路径)const char* filename = "input.mp4";if(avformat_open_input(&fmt_ctx, filename, nullptr, nullptr) != 0) {std::cerr << "无法打开文件" << std::endl;return -1;}// 查找视频流信息if(avformat_find_stream_info(fmt_ctx, nullptr) < 0) {std::cerr << "无法获取流信息" << std::endl;avformat_close_input(&fmt_ctx);return -1;}// 定位视频流int video_stream = -1;AVCodecParameters* codec_par = nullptr;for(int i = 0; i < fmt_ctx->nb_streams; i++) {if(fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {video_stream = i;codec_par = fmt_ctx->streams[i]->codecpar;break;}}if(video_stream == -1) {std::cerr << "未找到视频流" << std::endl;avformat_close_input(&fmt_ctx);return -1;}// 获取解码器const AVCodec* codec = avcodec_find_decoder(codec_par->codec_id);if(!codec) {std::cerr << "不支持的解码器" << std::endl;avformat_close_input(&fmt_ctx);return -1;}// 创建解码上下文AVCodecContext* codec_ctx = avcodec_alloc_context3(codec);avcodec_parameters_to_context(codec_ctx, codec_par);if(avcodec_open2(codec_ctx, codec, nullptr) < 0) {std::cerr << "无法打开解码器" << std::endl;avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);return -1;}// 初始化SWS转换上下文SwsContext* sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt,codec_ctx->width, codec_ctx->height, AV_PIX_FMT_RGB24,SWS_BILINEAR, nullptr, nullptr, nullptr);// 分配帧内存AVFrame* frame = av_frame_alloc();AVFrame* rgb_frame = av_frame_alloc();int buffer_size = av_image_get_buffer_size(AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1);uint8_t* buffer = (uint8_t*)av_malloc(buffer_size);av_image_fill_arrays(rgb_frame->data, rgb_frame->linesize, buffer,AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1);AVPacket* pkt = av_packet_alloc();cv::namedWindow("Video", cv::WINDOW_AUTOSIZE);// 主解码循环while(av_read_frame(fmt_ctx, pkt) >= 0) {if(pkt->stream_index == video_stream) {int ret = avcodec_send_packet(codec_ctx, pkt);if(ret < 0) continue;while(ret >= 0) {ret = avcodec_receive_frame(codec_ctx, frame);if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break;if(ret < 0) {std::cerr << "解码错误" << std::endl;break;}// 转换颜色空间sws_scale(sws_ctx, frame->data, frame->linesize, 0, codec_ctx->height,rgb_frame->data, rgb_frame->linesize);// 创建OpenCV Mat并显示cv::Mat img(codec_ctx->height, codec_ctx->width,CV_8UC3, rgb_frame->data);cv::imshow("Video", img);if(cv::waitKey(25) == 27) break; // ESC退出}}av_packet_unref(pkt);}// 清理资源av_free(buffer);av_frame_free(&frame);av_frame_free(&rgb_frame);av_packet_free(&pkt);sws_freeContext(sws_ctx);avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);cv::destroyAllWindows();return 0;
}
程序说明
-
FFmpeg初始化
使用avformat_open_input打开媒体文件
通过avformat_find_stream_info获取流信息 -
视频流处理
定位视频流索引
创建解码器上下文并打开 -
颜色空间转换
使用sws_getContext初始化转换上下文
将原始帧转换为RGB24格式 -
OpenCV显示
将转换后的RGB数据包装为cv::Mat
使用imshow显示视频帧
5 小结
VS2022配置FFMPEG库,在使用预编译包的情况下,没有特殊需要注意的,按照常规的第三方库配置思路进行配置即可。
相关文章:
VS2022配置FFMPEG库基础教程
1 简介 1.1 起源与发展历程 FFmpeg诞生于2000年,由法国工程师Fabrice Bellard主导开发,其名称源自"Fast Forward MPEG",初期定位为多媒体编解码工具。2004年后由Michael Niedermayer接任维护,逐步发展成为包含音视频采…...
kafka基本知识
什么是 Kafka? Apache Kafka 是一个开源的分布式流处理平台,最初由 LinkedIn 开发,后来成为 Apache 软件基金会的一部分。Kafka 主要用于构建实时数据管道和流处理应用程序。它能够高效地处理大量的数据流,广泛应用于日志收集、数…...
类型系统下的语言分类与类型系统基础
类型系统是一种根据计算值的种类对程序语法进行分类的方式,目的是自动检查是否有可能导致错误的行为。 —Benjamin.C.Pierce,《类型与编程语言》(2002) 每当谈到编程语言时,人们常常会提到“静态类型”和“动态类型”。…...
力扣-回溯-93 复原IP地址
思路 用一个vector存放可能的结果,然后用一个变量判断插入点的数量,假设再最后一段后也插入点 代码 class Solution { public:vector<string> result;vector<string> path;int toNum(string s){int d 1;int result 0;for(int i s.size…...
SpringSecurity设置白名单
Spring Security 访问权限系列文章: 《SpringSecurity基于配置方法控制访问权限:MVC匹配器、Ant匹配器》 《SpringSecurity基于注解实现方法级别授权:PreAuthorize、PostAuthorize、Secured》 《SpringSecurity设置白名单》 白名单࿰…...
有没有使用wxpython开发的类似于visio或drawio的开源项目(AI生成)
有没有使用wxpython开发的类似于visio或drawio的开源项目 是的,有一些使用wxPython开发的类似于Microsoft Visio或draw.io(现为diagrams.net)的开源项目。wxPython 是一个跨平台的GUI工具包,它允许Python开发者创建桌面应用程序&…...
HTML之JavaScript DOM操作元素(2)
HTML之JavaScript DOM操作元素(2) 4.增删元素var element document.createElement("元素名") 创建新元素父元素.appendChild(子元素) 在父元素中追加子元素父元素.insertBefore(新元素,参照元素) 在特定元素之前新增元…...
前端八股——JS+ES6
前端八股:JSES6 说明:个人总结,用于个人复习回顾,将持续改正创作,已在语雀公开,欢迎评论改正。...
day58 第十一章:图论part08
拓扑排序精讲 关键: 先找到入度为0的节点,把这些节点加入队列/结果,然后依次循环再找。 #include <iostream> #include <vector> #include <queue> #include <unordered_map> using namespace std; int main() {int …...
【MySQL 一 数据库基础】深入解析 MySQL 的索引(3)
索引 索引操作 自动创建 当我们为一张表加主键约束(Primary key),外键约束(Foreign Key),唯一约束(Unique)时,MySQL会为对应的的列自动创建一个索引;如果表不指定任何约束时,MySQL会自动为每一列生成一个索引并用ROW_I…...
【C++】优先级队列宝藏岛
> 🍃 本系列为初阶C的内容,如果感兴趣,欢迎订阅🚩 > 🎊个人主页:[小编的个人主页])小编的个人主页 > 🎀 🎉欢迎大家点赞👍收藏⭐文章 > ✌️ 🤞 …...
解决elementUi el-select 响应式不生效的问题
情况一,字段类型不匹配 考虑option的value值的字段类型是否和api返回的字段类型一致,如果一个为字符串一个为数字类型是无法匹配上的 <template> <div><el-select v-model"value" size"large"style"width: 240px"&…...
List 接口中的 sort 和 forEach 方法
List 接口中的 sort 和 forEach 方法是 Java 8 引入的两个非常实用的函数,分别用于 排序 和 遍历 列表中的元素。以下是它们的详细介绍和用法: sort 函数 功能 对列表中的元素进行排序。 默认使用自然顺序(如数字从小到大,字符…...
MusicGPT的本地化部署与远程调用:让你的Windows电脑成为AI音乐工作站
文章目录 前言1. 本地部署2. 使用方法介绍3. 内网穿透工具下载安装4. 配置公网地址5. 配置固定公网地址 前言 在如今快节奏的生活里,音乐不仅能够抚慰我们的心灵,还能激发无限创意。想象一下,在忙碌的工作间隙或闲暇时光中,只需输…...
小波变换背景预测matlab和python样例
小波变换使用matlab和python 注意1d和2d的函数区别。注意默认参数问题。最终三个版本结果能够对齐。 matlab load(wave_in.mat)% res: image of 1536 x 1536 th1; dlevel7; wavenamedb6;[m,n] wavedec2(res, dlevel, wavename);vec zeros(size(m)); vec(1:n(1)*n(1)*1) m…...
Unity通过Vosk实现离线语音识别方法
标注:deepseek直接生成,待验证 在Unity中实现离线语音识别可以通过集成第三方语音识别库来实现。以下是一个使用 Unity 和 Vosk(一个开源的离线语音识别库)的简单示例。 准备工作 Vosk:一个开源的离线语音识别库&am…...
【登月计划】 DAY2 中期:产品研发与设计验证(4-6)--《设计图纸如何从电脑飞进生产线?揭秘研发系统的 “暗箱操作”》
目录 四、乐高教学:拆解 CAD/CAE 与 PLM 的 “共生关系” 1. CAD 系统:工程师的 “数字画笔” 🎨 2. CAE 系统:产品的 “虚拟实验室” 🔬 3. PLM 系统:设计的 “大管家” 五、装逼话术:设计…...
智能优化算法:莲花算法(Lotus flower algorithm,LFA)介绍,提供MATLAB代码
一、 莲花算法 1.1 算法原理 莲花算法(Lotus flower algorithm,LFA)是一种受自然启发的优化算法,其灵感来源于莲花的自清洁特性和授粉过程。莲花的自清洁特性,即所谓的“莲花效应”,是由其叶片表面的微纳…...
Qt开源项目获取
GitHub上超实用的Qt开源项目,码住不谢!🎉 宝子们,今天来给大家安利一波GitHub上超棒的Qt开源项目,无论是学习还是开发,都能找到超多灵感和实用工具,快来看看有没有你需要的吧!1. Qt-Advanced-Docking-System完美的Dock窗口布局解决方案,让你的窗口管理变得超级灵活。…...
Python 高级特性-迭代
目录 迭代 练习 小结 迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。 在Python中,迭代是通过for ... in来完成的,而很多语言比如C语言&a…...
企业数据集成:实现高效调拨出库自动化
调拨出库对接调出单-v:旺店通企业奇门数据集成到用友BIP 在企业信息化管理中,数据的高效流转和准确对接是实现业务流程自动化的关键。本文将分享一个实际案例,展示如何通过轻易云数据集成平台,将旺店通企业奇门的数据无缝集成到用…...
基于GraphQL的电商API性能优化实战
以下是一个基于 GraphQL 的电商 API 性能优化实战案例,涵盖从问题分析到具体优化措施的实施过程: 一、初始问题分析 在电商场景下,随着业务发展,基于 GraphQL 的 API 出现了一些性能瓶颈。例如: 复杂查询导致响应时间过…...
UniApp SelectorQuery 讲解
一、SelectorQuery简介 在UniApp中,SelectorQuery是一个非常强大的工具,它允许开发者查询节点信息。通过这个API,我们可以获取到页面元素的尺寸、位置、滚动条位置等信息。这在处理动态布局、动画效果或是用户交互时尤为重要。 二、基本使用…...
数据库管理-第295期 IT架构与爆炸半径(20250221)
数据库管理295期 2025-02-21 数据库管理-第295期 架构与爆炸半径(20250221)1 术语新解2 硬件:存储VS本地盘3 数据库3.1 多模VS专用3.2 集中式VS分布式 4 公有云VS非公有云总结 数据库管理-第295期 架构与爆炸半径(20250221&#x…...
基于WOA鲸鱼优化的BiLSTM双向长短期记忆网络序列预测算法matlab仿真,对比BiLSTM和LSTM
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a/matlab2024b 3.部分核心程序 (完整版代码包含详细中文注释和操作步骤视频…...
DeepSeek私有化专家 | 云轴科技ZStack入选IDC中国生成式AI市场概览
DeepSeek 火爆全球AI生态圈,并引发企业用户大量私有化部署需求。 国际数据公司IDC近日发文《DeepSeek爆火的背后,大模型/生成式AI市场生态潜在影响引人关注》,认为中国市场DeepSeekAI模型的推出在大模型/生成式AI市场上引起了轰动,…...
linux下软件安装、查找、卸载
目录 常见安装方式有三种: 1.源码安装。 2.rpm安装方式。 3.yum/apt工具级别安装。 对于前两种安装方式,因为软件可能有依赖关系(安装的软件依赖于某些库,而这些库又依赖于某些库,这些都需要手动安装)…...
npm在install时提示要安装python问题处理
使用npm\yarn\pnpm下载以来的时候,一直提示python异常,有的项目安装了python之后,下载依赖还是异常 而且旧版本项目使用python2,新的使用Python3…很烦 解决方案1:cnpm 安装教程: npm安装cnpm,解决node12\…...
Nginx代理ElasticSearch
1、将ES的账号:密码通过Base64加密 假设账号密码如下: 账号:elastic密码:elastichuayunworld.com echo -n elastic:elastichuayunworld.com | base64 ZWxhc3RpYzplbGFzdGljQGh1YXl1bndvcmxkLmNvbQ2、在 Nginx 配置中传递认证信息 locatio…...
如何将MySQL数据库迁移至阿里云
将 MySQL 数据库迁移至阿里云可以通过几种不同的方法,具体选择哪种方式取决于你的数据库大小、数据复杂性以及对迁移速度的需求。阿里云提供了多种迁移工具和服务,本文将为你介绍几种常见的方法。 方法一:使用 阿里云数据库迁移服务 (DTS) 阿…...
