当前位置: 首页 > article >正文

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库,在使用预编译包的情况下,没有特殊需要注意的,按照常规的第三方库配置思路进行配置即可。


http://www.kler.cn/a/558868.html

相关文章:

  • 视频mp4垂直拼接 水平拼接
  • Vulhub靶机 Apache Druid(CVE-2021-25646)(渗透测试详解)
  • 【Python爬虫(44)】分布式爬虫:筑牢安全防线,守护数据之旅
  • 如果后台的Long类型的数据返回是null,那么Android客户端的数据bean的kotlin的Long类型的字段接受到数据后是null空指针吗?
  • 20250223学习记录
  • The Heliosphere 日球层
  • 机器学习数学通关指南——拉格朗日乘子法
  • Hadoop常用操作命令
  • w803|联盛德|WM IoT SDK2.X测试|window11|手动编译|(3):编译环境搭建
  • 现代任务调度系统架构深度解析——以TaskSchedulerController为核心的弹性任务管理方案
  • 第1章 Vue设计哲学(深度解析版)
  • ReACT agent和FC agent
  • 纯CPU跑DeepSeek-R1 671b大模型
  • Pytorch深度学习教程_5_编写第一个神经网络
  • windows下安装CUDA-本地微调大模型
  • JUC并发—11.线程池源码分析
  • 通过Hive小文件合并(CombineHiveInputFormat)减少80%的Map任务数
  • w803|联盛德|WM IoT SDK2.X测试|window11|VSCODE|(4):IDE配置
  • 解决Open WebU无法显示基于OpenAI API接口的推理内容的问题
  • 【开源项目】分布式文本多语言翻译存储平台