一Windows 音视频开发环境搭建

Posted 想文艺一点的程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一Windows 音视频开发环境搭建相关的知识,希望对你有一定的参考价值。

目录

1、FFmpeg

1.1、为什么是 FFmpeg

每个主流平台基本都有自己的音视频开发库(API),用以处理音视频数据,比如:

  • ios:AVFoundation、AudioUnit等
  • android:MediaPlayer、MediaCodec等
  • Windows:DirectShow

为了让所有平台的开发者都能够学习到音视频开发的通用技术,本教程主要讲解跨平台的音视频开发库FFmpeg。其实只要你掌握了FFmpeg,也可以很快上手其他音视频开发库,因为底层原理都是一样的,你最终操作的都是一样的数据,比如MP3、MP4文件。


1.2、FFmpeg 简介

FFmpeg的名字由FF和mpeg组成。

  • FF是 Fast Forward(译为:快进、快速前进)的简称
  • mpeg来源于Moving Picture Experts Group(简称:MPEG,译为:动态影像专家小组)
    • MPEG是源自ISO与IEC等国际组织的工作小组
    • MPEG的其中一项工作是:制定音视频相关的标准(比如压缩标准)

有很多知名项目都采用了FFmpeg,比如:

  • Google Chrome:浏览器
  • Firefox:浏览器
  • VLC:跨平台播放器
  • MPlayer
  • ijkplayer:bilibili团队开发的Android/iOS播放器框架
  • Perian:Apple公司的QuickTime组件

1.3、FFmpeg 下载

FFmpeg 是一个开源项目,源码也是开放出来的。所以一般有两种下载方式:

  • 下载源码:自己可以对其源码进行修改,增加或者裁剪,然后自己进行编译
  • 已经编译好的:这个是官方进行编译好了,这里将官方的源码都进行了编译。这个是完整版,体积比较大。

第一种:源码下载,直接去官网下载即可,下列是文件列表(我们不做分析)

第二种:已经编译好的下载,以下是各个文件。

  • bin:可执行文件。
  • doc:参考文档,就是官网上面的文档,我们可以离线观看。
  • include:头文件,我们进行二次开发使用。
  • lib:动态库文件,我们进行二次开发使用。
  • preset:预设文件。

    二次开发:
  • include:头文件,用于链接时候索引 lib 当中的 API。
  • lib:动态库文件,里面是编译好的 API 程序,我们程序运行过程当中会调用它。

2、QT 下载安装

略过:
可以参考文章:https://www.cnblogs.com/mjios/p/14465178.html#toc_title_5


3、ffmpeg 的lib集成到 QT 项目

在Windows中,我们最终是通过调用FFmpeg动态库(dll)中的函数来操作音视频数据,使用dll的其中一种方式是需要用到 3种文件

第一种:头文件( xxx.h 文件)

  • 包含了函数的声明
  • 通过#include去导入相应的头文件

第二种:(动态链接库的)导入库(Import Library)文件。
不同编译器,使用的文件格式不同:

  • .lib:用于MSVC编译器中
  • .dll.a:用于MinGW编译器中

但是作用是相同的:

  • 包含了dll中函数的入口,用于辅助找到,并调用dll中的函数。
  • 最终需要链接到Windows程序中(比如合并到exe文件中)

第三种:动态链接库(Dynamic Link Library)( .dll

  • 包含了函数的具体实现代码
  • Windows程序会在运行过程中,动态调用dll中的函数

值得一提的是,在Windows中,静态链接库(Static Link Library)的扩展名也是.lib、.dll.a。静态链接库和导入库的区别是:

  • 静态链接库:包含了函数的具体实现代码
  • 导入库:不包含函数的具体实现代码(函数的具体实现代码存储在dll中)

3.1、修改 QT 的pro文件

Pro 文件是对编译器进行配置,指导编译器去哪里寻找动态库哪里寻找头文件 等等。

INCLUDEPATH += :增加头文件的搜索路径。
LIBS += :指定链接库

注意:

  • 需要自己实现 FFMPEG_HOME,指定 ffmpeg 的根目录。
  • #号后面的内容是注释
  • -L:设置导入库的目录,以便编译器能够找到导入库
  • -l:link 设置需要链接的导入库名称
# 库文件的根目录
win32
    FFMPEG_HOME = D:/openlib/ffmpeg-4.4.1-full_build-shared


macx
    FFMPEG_HOME = ..


# 设置头文件的目录,以便编译器能够找到头文件
INCLUDEPATH += $$FFMPEG_HOME/include
# 设置导入库的目录和需要链接的导入库
LIBS += -L $$FFMPEG_HOME/lib \\
        -lavcodec \\
        -lavdevice \\
        -lavfilter \\
        -lavformat \\
        -lavutil \\
        -lpostproc \\
        -lswscale \\
        -lswresample

实际的动态库文件如下图所示,但是在 pro 文件当中链接的时候需要注意名称
(前面加 -l 代表 -link,拓展名 .lib 去掉)

编写代码测试:

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>

// FFmpeg是C语言库
// 有了extern "C",才能在C++中导入C语言函数
extern "C" 
    #include <libavcodec/avcodec.h>


int main(int argc, char *argv[])

    QApplication a(argc, argv);
    MainWindow w;
    qDebug()<< av_version_info();

    w.show();
    return a.exec();

运行结果:

4.4.1-full_build-www.gyan.dev

如果不能运行:
1、先测试一下 Qt 能不能搜索到对应的头文件,在 #include 的时候,IDE 会提示路径。
2、多半是 pro 文件对 变量的解引用问题$$FFMPEG_HOME ,可以先取消变量,直接将路径贴过去看看能不能使用。


3.2 .exe 程序正常运行

现在的程序在 Qt 里面编译的时候可以运行,但是双击生成的 .exe 文件却不能运行。
原因:系统找不到 qt、ffmpeg 的动态库

解决办法:
1、找到这些动态库的位置
2、解决系统无法定位的问题

3.2.1 寻找 .dll 文件

使用 everything 搜索对应库的名称,虽然有很多的动态库文件,但是我们应该使用 Qt 的IDE当中自带的

3.2.2 系统对 dll 文件的搜寻顺序

exe在寻找dll文件时,大概按照以下优先级顺序去查找(这里只列出了大概的搜索路径,并没有写全):

(1).exe 所在的目录
(2)Windows 的 System目录

  • C:/Windows/System
  • C:/Windows/System32

(3)Windows目录:C:/Windows

(4)环境变量Path中的路径

我个人一般使用第四种方法,将动态库的路径配置到环境变量当中。

第1种方式需要在每一个Qt程序中都拷贝一份FFmpeg的dll文件,第2~4种方式可以让多个Qt程序共用同一份FFmpeg的dll文件。


4、SDL

(1)ffplay 是基于FFmpeg、SDL两个库实现的。通过编程的方式播放音视频,也是需要用到这2个库。FFmpeg大家都已经清楚了,比较陌生的是SDL。

(2)SDL(Simple DirectMedia Layer),是一个跨平台的C语言多媒体开发库

  • 支持Windows、Mac OS X、Linux、iOS、Android
  • 提供对音频、键盘、鼠标、游戏操纵杆、图形硬件的底层访问
  • 很多的视频播放软件、模拟器、受欢迎的游戏都在使用它
  • 目前最新的稳定版是:2.0.14
  • API文档:wiki

(3)SDL官网下载地址:https://www.libsdl.org/download-2.0.php

(4)解压后的目录结构如下图所示,跟FFmpeg的目录结构类似,因此就不再赘述每个文件夹的作用。

  • 其中 i686 代表 windows 32位的机器。 x86 代表 windows 64位的机器。


4.1 SDL 的qt集成遇到的问题

(1)问题一:没有权限

原 pro 文件

# 库文件的根目录
win32
    FFMPEG_HOME = D:/openlib/ffmpeg-4.4.1-full_build-shared
    SDL_HOME = D:/openlib/SDL2-2.0.22/x86_64-w64-mingw32


macx
    FFMPEG_HOME = ..


# 设置头文件的目录,以便编译器能够找到头文件
INCLUDEPATH += $$FFMPEG_HOME/include
INCLUDEPATH += $$SDL_HOME/include

# 设置导入库的目录和需要链接的导入库
LIBS += -L $$FFMPEG_HOME/lib \\
        -lavcodec \\
        -lavdevice \\
        -lavfilter \\
        -lavformat \\
        -lavutil \\
        -lpostproc \\
        -lswscale \\
        -lswresample


LIBS += -L $$SDL_HOME/lib \\
        -lSDL2

原因:LIBS 链接的时候:-L 后面不能有空格。
修改:

LIBS += -L$$FFMPEG_HOME/lib \\
        -lavcodec \\
        -lavdevice \\
        -lavfilter \\
        -lavformat \\
        -lavutil \\
        -lpostproc \\
        -lswscale \\
        -lswresample


LIBS += -L$$SDL_HOME/lib \\
        -lSDL2

(2)问题二:找不到 main 函数。

原文件:

#include "SDL2/SDL.h"

修改:

extern "C"
    #include "SDL2/SDL.h"
    #undef main

以上是关于一Windows 音视频开发环境搭建的主要内容,如果未能解决你的问题,请参考以下文章

一Windows 音视频开发环境搭建

PyQt5快速上手基础篇1-开发环境搭建

FFmpeg windows软件开发环境搭建

1开发环境搭建

ESP32上手笔记 | 02 - ESP32-Arduino开发环境搭建

ESP32上手笔记 | 02 - ESP32-Arduino开发环境搭建