水了这么多篇,是时候开始干正事了。
Linux基础知识已经掌握了,现在可以开始编译ffmpeg了:
一、下载ffmpeg
首先下载ffmpeg的源代码,ffmpeg所有版本源代码下载地址:
截至本文编写时,ffmpeg最新版本是3.3,但我们还是一如既然的使用2.5.6.
2.5.6下载地址: http://ffmpeg.org/releases/ffmpeg-2.5.6.tar.gz
二、编译ffmpeg
将下载到的ffmpeg-2.5.6.tar.gz 复制到linux下并解压出来(直接右键解压就行)
然后打开终端,开始编译:
1)进入ffmpeg目录
cd ffmpeg-2.5.6
2)配置生成makefile文件
./configure --prefix=../ffmpeg --disable-yasm --enable-shared --disable-static
其中--prefix=../ffmpeg表示的是最后编译生成的文件存放路径,如果不指定这个路径,会默认安装到/usr/local目录下,这样后面编译的程序一多,就乱套了,因此不建议用默认的。
--disable-yasm表示的是禁用汇编,因为我们的系统是刚刚安装的,基本上的工具都没有安装,因此先禁用汇编。我们先不关心效率上的问题,先成功编译了再说。
--enable-shared --disable-static 就是只编译动态库,不编译静态库。为了更好的讲解如何在运行的时候引用动态库的so,这里我们只编译动态库。
configure的时候,可以指定的参数还很多,我们先不管他。
不出意外的话,这一步执行完毕,将会生成Makefile文件,下面就可以执行make命令来编译了。
3)编译
make -j 16
make后面跟着 -j 16表示的是使用16个线程来编译,可以大大提高编译速度,我用的是I5的CPU,大家可以根据自己的CPU能力,分配线程数量。
编译的过程需要很长的时间,完全看个人CPU的能力。
4)安装
make install
这一步就是将上面编译生成的库文件以及一些头文件复制到前面指定的目录中(--prefix=../ffmpeg)。
最终,便可看到生成了一个ffmpeg文件夹,里面有Include和lib目录。
三、引用ffmpeg
现在写一个简单的程序来引用ffmpeg吧,跟windows下第一次使用ffmpeg的教程一样,我们还是调用avcodec_version来打印一个版本信息,只不过这次我们换成了C语言,因为我们还没有安装c++的编译器。
使用gedit hello_ffmpeg.c新建一个c文件,输入如下内容:
#include <stdio.h> #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libswscale/swscale.h" #include "libavdevice/avdevice.h" int main() { //这里简单的输出一个版本号 printf("Hello FFmpeg!"); av_register_all(); unsigned int version = avcodec_version(); printf("version is: %d ", version); return 0; }
OK,保存,编译:
gcc -o hello_ffmpeg hello_ffmpeg.c
这里会报一堆的错误,因为我们并没有指定ffmpeg的路径,指定的方法也很简单,只需要将编译命令做如下修改即可:
gcc -o hello_ffmpeg hello_ffmpeg.c -Iffmpeg/include -Lffmpeg/lib/ -lavdevice -lavformat -lavfilter -lavcodec -lswscale -lavutil -lswresample
现在回过头来看下当初我们在windows下Qt引用ffmpeg的时候,pro文件里面的内容,是不是觉得基本一样。
这里需要注意的一点就是,hello_ffmpeg.c这个文件要和上面编译生成的ffmpeg在同一个目录下(我都是放在桌面上),如果不是同一个目录,就需要修改上面的路径:-Iffmpeg/include -Lffmpeg/lib/
四、运行程序
编译成功后,会生成一个hello_ffmpeg的可执行程序,相信有了前面几节的hello word作为铺垫,大家都知道如何运行这个程序了,直接执行./hello_ffmpeg即可.
遗憾的是,这一次我们失败了:
因为我们引用了ffmpeg的库,所以运行的时候提示找不到库文件了。
在windows下,我们只需要将这些dll和exe程序放到同一个目录即可,然后linux并没有这么简单,Linux有多个办法解决这个问题,我知道的有2个:
1.将这些so直接复制到系统/lib目录下
2.运行直接修改LD_LIBRARY_PATH变量
方法一直接pass掉,这个办法真的不推荐,举个简单的例子,我们有2个程序,分别调用了不同版本的ffmpeg的库,要是都放到/lib目录下,那不是很坑爹!
那么看下方法二吧:
打开终端,切到之前编译生成的ffmpeg所在的目录(我的是桌面),执行如下命令:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:ffmpeg/lib
这句话的意思,给LD_LIBRARY_PATH这个变量添加一个 ffmpeg/lib
这样程序在运行的时候,就会去ffmpeg/lib目录下查找库文件。
现在接着执行./hello_ffmpeg
会看到程序运行起来了,并打印出了ffmpeg的版本信息。
需要注意的是,上面修改变量的操作只对这个终端有效,可以试下打开一个新的终端运行程序,一样还是提示库找不到。
那么问题来了,如此长的命令,每次运行之前都要运行一遍不是非常坑爹么,而且还只对这个终端有效。
一个非常好的解决办法就是将上面的这两条命令写入一个bash文件(类似windows的bat):
以后每次运行只需要执行这个脚本文件就行了,我用的就是这个方法,因为我非常讨厌将库文件直接放到/lib目录下。
bash文件自己去研究,我不讲。
学习音视频技术欢迎访问 http://blog.yundiantech.com
音视频技术交流讨论欢迎加 QQ群 121376426