一年前毕业,阴差阳错最终还是入了硬件的坑,而且是比较硬的那种,一点软件都不带的。白瞎了我大学把STM32学的那么好,最后还是嫌弃嵌入式给的工资低选了硬件。
一年了,游戏越打越无聊,至于女朋友,那更是:十方无影像,六道绝形踪。跳出三界外,不在五行中。工作之余总得给自己找点事情做,想起一年前下载别人的代码,利用别人ffmpeg+sdl搭建的播放器框架,加入opencv做的控制台字符串播放badapple。当时只是了解了一点皮毛,在源代码上乱改一通,最终完成了。
最近闲来无事,打算重新系统的了解一下fmpeg+opencv+sdl这三个开源工程,从头搭建一个播放器,在保证视音频同步播放的同时,提供一个接口,把播放的每一帧图片取出来,以便可以做一些各种各样的处理,无论是转换为字符串还是其它的什么骚操作。短期的目标就是这样。
一般来说,常见的环境搭建都是配置环境变量,但我本人对这种方法深恶痛绝,毕竟源码复制到别的电脑是就又得重新搞一遍环境,或者有时候不知道哪里又搞出了幺蛾子,导致编译挂掉,还得从头来一遍。
所以我一把的做法是下载源码直接添加的工程中,以便至少在Win10/vs2017环境下,在不同的电脑上做到,一次编写,处处运行。
废话不多说,这三个源码你都需要在其对应的官网下载,记得下载的时候选win——64位,opencv是放在一个exe(其实就是压缩包),记的下载WIN环境下的64位的,我下的都是最新的。下载完成后你得到3个压缩包和一个exe;如下:
事实上,ffmpeg有三个压缩包,我们只需要shared和dev两个压缩包
解压后,对于ffmpeg 你只需要关注dev下的include/lib这两个文件夹,这两个文件放了对应的库文件和头文件,shared里的文件我们需要bin文件夹下的dll文件,这个后面再讲
同理对于,SDL解压后,你也只需要关注include/lib这两个文件夹,注意lib文件夹下有两个文件夹:x64和x86;对于我来说,我只需要X64下的库文件,至于x86我直接删除了;我们要用到的文件为include以及lib这两个文件夹下的内容
对于opencv,exe文件其实质也是一个压缩包,打开后得到以下内容
build文件夹下是我们需要的内容,source文件夹可以删除了,build文件夹下我们需要关注include和X64两个文件夹,X64下有两个文件夹,分别是vc14/vc15;对于我来说vs2017对应vc15版本,因此vc14文件夹可以删除了
VC14,Visual Studio 2015编译器
VC15,Visual Studio 2017编译器
到这里我们会得到三个文件夹
其中ffmpeg放的是解压缩后得到:include、lib文件夹;
opencv下放的是解压后build文件夹下的:include、x64文件夹
SDL2-2.0.10文件夹下放的是解压缩后得到的include、lib文件夹,其他文件夹不必关注,我只是没有删除而已
注意,以上文件夹均是直接拷贝过来,你可以删除你不需要的文件夹,比如x86文件夹,vc14文件夹,但是不要轻易更改文件夹的路径,比如把x64——vc15下的文件直接剪切到x64下,删除vc15。不要做这些操作,否则后续路径会很麻烦。
现在打开vs2017,新建控制台程序,新建一个工程,我这里工程取名为001,打开工程的路径
在001.sln所在的目录下,有一个001的文件夹(与你的工程名字相同),打开它
这里有建立工程时自动生成的.h和.cpp文件,在这里新建一个名为library的文件夹(注意如果要拷贝我提供的路径,这个文件夹命名必须为library),把之前得到的三个文件夹拷贝到这里,最终打开如下:
工程编编译器选择如下:release x64
工程建立完成后添加路径:
在属行——VC++目录:库目录添加:
library\ffmpeg\lib;
library\opencv\x64\vc15\bin;
library\opencv\x64\vc15\lib;
library\SDL2-2.0.10\lib\x64;
在C/C++——常规:附加包含目录添加:(直接拷贝,鼠标放到对应方框内最前面粘贴即可)
library\ffmpeg\include;library\opencv\include;library\SDL2-2.0.10\include;library\ffmpeg\include\libavcodec;library\ffmpeg\include\libavdevice;library\ffmpeg\include\libavfilter;library\ffmpeg\include\libavformat;library\ffmpeg\include\libavutil;library\ffmpeg\include\libpostproc;library\ffmpeg\include\libswresample;library\ffmpeg\include\libswscale;library\opencv\include\opencv2;library\opencv\include\opencv2\calib3d;library\opencv\include\opencv2\core;library\opencv\include\opencv2\dnn;library\opencv\include\opencv2\features2d;library\opencv\include\opencv2\flann;library\opencv\include\opencv2\gapi;library\opencv\include\opencv2\highgui;library\opencv\include\opencv2\imgcodecs;library\opencv\include\opencv2\imgproc;library\opencv\include\opencv2\ml;library\opencv\include\opencv2\objdetect;library\opencv\include\opencv2\photo;library\opencv\include\opencv2\stitching;library\opencv\include\opencv2\video;library\opencv\include\opencv2\videoio;
在 链接器——输入:附加依赖项添加:(直接拷贝,鼠标放到对应方框内粘贴即可)
avcodec.lib;avdevice.lib;avfilter.lib;avformat.lib;avutil.lib;postproc.lib;swresample.lib;swscale.lib;opencv_world411.lib;SDL2.lib;SDL2main.lib;SDL2test.lib
在 VC++——预编译头:更改为 不使用预编译头
至此环境搭建完毕
进入工程,将工程自动建立的cpp和hpp文件移除(删除),重新建立自己的主函数,如果你的程序主函数为main,且包含了头文件#include "SDL.h",会报错误如下:
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK2001 无法解析的外部符号 main 001 D:\VsWork\001\001\MSVCRT.lib(exe_main.obj) 1
在sdl_main.h下找到这个
#define main SDL_main;注释掉即可,不影响使用
注意所有用到的DLL文件需要放在工程生成的exe目录下,程序才能运行,它们是
library\opencv\x64\vc15\bin下的: opencv_world411.dll
library\SDL2-2.0.10\lib\x64下的: SDL2.dll
对于ffmpeg,还记得ffmpeg-4.2.1-win64-shared这个压缩包吗,在ffmpeg-4.2.1-win64-shared\bin这个里面有我们需要的dll文件,复制出来:
拷贝到生成exe文件的目录下
分别用sdl和opencv显示图片,运行显示图片如下:
opencv显示图片代码,网上随便一搜到处都是,sdl网上也有现成的显示BMP图片的代码,如果要显示其它格式需要对RGB像素格式转化,具体如何实现以后有空再写。
注意:ffmpeg头文件包含时需要加
extern "C" {
#include "avformat.h"
#include "avcodec.h"
#include "avutil.h"
#include "swresample.h"
#include "swscale.h"
#include "time.h"
}
测试ffmpeg读取显示视频信息如下:
如果测试运行正常,环境搭建测试至此完成。
说点题外话,有人会问了,你不是最求源文件吗?问什么还下载编译后的lib文件+dll的方式搭建环境,为什么不干脆直接下载源代码.cpp文件,直接放入工程中,这样甚至可以直接修改源代码,你别说我还真干过这事,结果就是,整个工程编译起来极其耗费时间,所以还是老老实实的用lib+dll吧。
其实这样做也会有代价,那就是整个工程特别大,因为library文件夹就有500M左右,再加上编译后生成的隐藏文件,整个工程大小在1G左右,相对于配置环境变量来说,工程文件夹相对会比较大,比较占硬盘,好在现在硬盘越做越大。