ffmpeg:windows编译及使用(vs2019编译)

前言

本章节记录在Windows上编译ffmpeg的过程及编译过程的问题,并使用编译库编写测试程序验证是否可用。

在windows上编译主要使用MSYS2和vs 2019编译器编译ffmpeg,并且验证32位和64位的编译。

环境准备

  • ffmpeg源代码

    官网:https://ffmpeg.org/

    版本:FFmpeg 5.1.2 “Riemann”

    版本信息:

    5.1.2 was released on 2022-09-25. It is the latest stable FFmpeg release from the 5.1 release branch, which was cut from master on 2022-07-13.

    It includes the following library versions:

    libavutil      57. 28.100
    libavcodec     59. 37.100
    libavformat    59. 27.100
    libavdevice    59.  7.100
    libavfilter     8. 44.100
    libswscale      6.  7.100
    libswresample   4.  7.100
    libpostproc    56.  6.100
    
  • 系统版本:Windows 10

  • 编译器:Visual Studio 2019

  • MSYS2

    MSYS2是Windows下的Linux模拟器,支持绝大多数的Linux命令,软件包管理器是pacman

    官网:https://www.msys2.org/

    版本:msys2-x86_64-20221028.exe

  • x264源代码

    x264是一个用于将视频流编码为H.264/MPEG-4 AVC压缩格式的免费软件库和应用程序。为了支持ffmpeg的H264编解码必须编译这个。

    官网:https://www.videolan.org/developers/x264.html

    版本:master分支(20221112)

编译

  1. 启动msys2

    通过vs2019的命令行启动msys2,这样msys2可以获取到vs的环境变量。

    编译32位和64位的动态库,只是启动的vs2019命令行不一样,其他执行操作都一样。下面以编译32位的动态库为例,启动msys2:

    1. 修改msys2的配置文件

      修改msys2_shell.cmd文件,打开set MSYS2_PATH_TYPE=inherit的注释(使其能继承vs2019的命令行环境)

    在这里插入图片描述

    1. 启动vs2019 x86(32位)命令行

      如下可以看到32和64的命令行,这里我们启动x86 Native ToolsCommand Prompt for Vs2019

      在这里插入图片描述

    2. 测试cl.exe的版本确实是x86(32)

      在这里插入图片描述

    3. 启动msys2

      启动mysy2(c:\msys64是msy2的安装目录),不管启动的vs2019命令行是32位还是64位的,执行下面操作都一致。

      在这里插入图片描述

      启动后的msys2:

      在这里插入图片描述

  2. 安装依赖项

    # 安装mingw工具链
    pacman -S mingw-w64-x86_64-toolchain
    
    # 安装linux base-devel
    pacman -S base-devel
    
    # 安装汇编工具,gcc等
    pacman -S yasm nasm gcc
    
  3. 源代码解压

    将ffmpeg和x264源码解压放在如下对应目录:

    在这里插入图片描述

  4. 编译

    1. 编译脚本整理如下,该编译文件放置在x264-master和ffmpeg-5.1.2的同级目录。切换到该脚本目录执行脚本。
    # 当前脚本的目录
    base_path=$(cd `dirname $0`;pwd)
    
    # 设置输出目录:64还是32位
    archtarget="x64"
    isContrainX64=$(which cl)
    
    if [[ $isContrainX64 =~ $archtarget ]];then
    	archtarget="x64"
    else
    	archtarget="win32"
    fi
    
    echo $archtarget
    
    # x264的源文件目录和编译后的安装目录
    x264_src_path=$base_path/x264-master
    x264_lib_path=$base_path/install/$archtarget/x264
    
    # ffmpeg的源文件目录和编译后的安装目录
    ffmpeg_src_path=$base_path/ffmpeg-5.1.2
    ffmpeg_lib_path=$base_path/install/$archtarget/ffmpeg
    
    # -------------编译x264-------------
    echo "[info] begin compile x264"
    
    cd $x264_src_path
    
    CC=cl ./configure --prefix=$x264_lib_path --enable-static
    
    make clean
    make -j8
    if [ $? -eq 0 ];then
    	echo "[info] x264 build sucessed."
    else
    	echo "[error] x264 build failed."
    	exit 1
    fi
    
    make install
    
    # -------------编译ffmpeg静态库-------------
    echo "[info] begin compile ffmpeg"
    
    export  PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$x264_lib_path/lib/pkgconfig
    
    cd $ffmpeg_src_path
    
    # --prefix:生成文件目录
    # --enable-shared:构建shared库
    # --arch:目标架构(常用有aarch64,arm,ia64,x86,x86_32,x86_64)
    # --enable-libx264:通过x264使用h.264编码 #类似 
    # --enable-libopenh264
    # --extra-cflags:(c)编译参数 # --extra-cflags="-MDd" debug版本
    # --extra-libs:链接参数 
    # --extra-ldflags="/NODEFAULTLIB:libcmt"
    # --enable-debug:debug版本
    # --toolchain:使用编译器vs2019
    CC=cl ./configure --prefix=$ffmpeg_lib_path --enable-shared --enable-libx264 --enable-gpl --arch=x86 --toolchain=msvc \
    --extra-cflags=-l$x264_lib_path/include \
    --extra-ldflags=-L$x264_lib_path/lib
    
    # 修改config.h的内容,防止中文字符引起不能编译
    # #define CC_IDENT "用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30146 版" -> #define CC_IDENT "Microsoft (R) C/C++"
    sed -i "/#define CC_IDENT.*/c\#define CC_IDENT \"Microsoft (R) C/C++\"" config.h
    
    make clean
    make -j8
    if [ $? -eq 0 ];then
    	echo "[info] ffmpeg build sucessed."
    else
    	echo "[error] ffmpeg build failed."
    	exit 1
    fi
    
    make install
    
    # 保存PDB
    mkdir $ffmpeg_lib_path/pdb
    find . -iname "*.pdb" -type f -exec cp {} $ffmpeg_lib_path/pdb \;
    
    exit 0
    
  5. 编译好的动态库已经打包好了,包含32位和64位的动态库,下载地址:ffmpeg在Windows上vs2019编译的动态库(32位和64位包含pdb)-编解码文档类资源-CSDN文库

测试

编写测试程序测试是否可用,测试获取视频文件的时长。

测试代码:

extern "C"
{
#include <libavformat/avformat.h>
}

#include <iostream>

bool getVedioDuration(const std::string &filePath)
{
    AVFormatContext *fmtCtx = avformat_alloc_context();
    if (nullptr == fmtCtx)
    {
        return false;
    }
    auto ret = avformat_open_input(&fmtCtx, filePath.c_str(), NULL, NULL);
    if (ret < 0)
    {
        return false;
    }

    int videoIndex = -1;
    int audio_index = -1;
    int nbStreams = fmtCtx->nb_streams;
    for (int i = 0; i < nbStreams; i++)
    {
        // fmtCtx->streams[i]->codec 新版ffmpeg已弃用
        if (fmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            videoIndex = i;
        }
        else if (fmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
        {
            audio_index = i;
        }
    }

    if (videoIndex != -1)
    {
        auto streamVedio = fmtCtx->streams[videoIndex];

        std::cout << "vedio duration: " << (streamVedio->duration * streamVedio->time_base.num / streamVedio->time_base.den) << std::endl;
    }

    if (audio_index != -1)
    {
        auto streamAudio = fmtCtx->streams[audio_index];
        std::cout << "audio duration: " << (streamAudio->duration * streamAudio->time_base.num / streamAudio->time_base.den) << std::endl;
    }

    if (videoIndex == -1 && audio_index == -1)
    {
        return false;
    }

    return true;
}


int main(int argc, char *argv[])
{
    getVedioDuration("D:\\vedio\\aa.mp4");

    return 0;
}

基于Qt的工程配置

# 项目根目录
ROOT_DIR = $$PWD/..

# 第三方库
3RDPART_DIR = $${ROOT_DIR}/3rdparty

# 可执行目录
CONFIG(debug, debug|release){
BIN_DIR = $${ROOT_DIR}/debug
} else {
BIN_DIR = $${ROOT_DIR}/release
}

win32 {
    contains(QMAKE_TARGET.arch, x86_64) {
        # x64
        INCLUDEPATH += $${3RDPART_DIR}/ffmpeg/x64/include
        CONFIG(debug, debug|release){
            LIBS += -L$${3RDPART_DIR}/ffmpeg/x64/bin \
                    -lavformat
        } else {
            LIBS += -L$${3RDPART_DIR}/ffmpeg/x64/bin \
                    -lavformat
        }
    } else {
        # x86
        INCLUDEPATH += $${3RDPART_DIR}/ffmpeg/win32/include
        CONFIG(debug, debug|release){
            LIBS += -L$${3RDPART_DIR}/ffmpeg/win32/bin \
                    -lavformat
        } else {
            LIBS += -L$${3RDPART_DIR}/ffmpeg/win32/bin \
                    -lavformat
        }
    }
}

其他

  • 编译过程中出现make install报错

    问题现象:在编译x264的时候,make install报错,msys2 make: install: No such file or directory

    解决:未找到正式原因,将msys2卸载后,重新安装,并安装依赖环境解决

  • 编译ffmpeg出现CC_IDENT引起的编译错误

    问题现象:译ffmpeg出现CC_IDENT引起的编译错误

    原因:configure后,会根据cl的版本信息写入config.h的头文件中,因中文版本原因,CC_IDENT包含中文字符,编译时不识别报错

    解决:编译脚本中已修改如下

    sed -i “/#define CC_IDENT.*/c#define CC_IDENT “Microsoft ® C/C++”” config.h

  • 编译ffmpeg 64位时卡住

    现象:编译ffmpeg 64时在如下地方卡住:

    LD      libavcodec/avcodec-59.dll
      正在创建库 libavcodec/avcodec.lib 和对象 libavcodec/avcodec.exp
    

    解决:重新使用vs 2016 x86_64的命令行编译通过

    在这里插入图片描述

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要在VS2019编译FFmpeg,你需要按照以下步骤进行操作: 1. 下载FFmpeg源代码:你可以从FFmpeg的官方网站(https://ffmpeg.org/)或者GitHub仓库(https://github.com/FFmpeg/FFmpeg)下载最新的源代码。 2. 安装MSYS2:FFmpeg使用MSYS2作为构建环境,因此你需要先安装MSYS2。你可以从官方网站(https://www.msys2.org/)下载最新的安装程序,并按照提示进行安装。 3. 打开MSYS2:安装完成后,打开MSYS2的命令行终端。 4. 更新MSYS2:在MSYS2的命令行终端中,运行以下命令更新系统: ``` pacman -Syu ``` 5. 安装所需的依赖项:使用以下命令安装构建FFmpeg所需的依赖项: ``` pacman -S mingw-w64-x86_64-toolchain nasm git ``` 6. 配置环境变量:将MSYS2的bin目录添加到系统的PATH环境变量中。默认情况下,MSYS2的bin目录位于C:\msys64\usr\bin。 7. 克隆FFmpeg源代码:在MSYS2的命令行终端中,使用以下命令克隆FFmpeg的源代码: ``` git clone https://github.com/FFmpeg/FFmpeg.git ``` 8. 进入FFmpeg目录:使用cd命令进入FFmpeg源代码的目录: ``` cd FFmpeg ``` 9. 配置编译选项:使用以下命令配置编译选项(可以根据需要进行调整): ``` ./configure --prefix=/usr/local --enable-shared --disable-static ``` 10. 编译和安装:使用以下命令开始编译和安装FFmpeg: ``` make make install ``` 11. 完成:编译完成后,你可以在/usr/local目录下找到生成的FFmpeg可执行文件和库文件。 请注意,编译FFmpeg可能需要一些时间,并且可能会因为系统配置和依赖项的不同而出现问题。如果遇到任何错误,请参考FFmpeg的官方文档或寻求帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaobaiPlayGame

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值