FFmpeg是非常强大的编解码库,支持相当多的格式。如果你仔细看一下手机中各种播放器的许可条款,一定不会缺少FFmpeg的身影。
但是网络上FFmpeg移植的资料都非常少,很多还是使用很老的库,比如使用2.xx版本的FFmpeg,NDK版本还使用r9(2019年最新的NDK版本已经到了r21)。但是程序员一定是要与时俱进的嘛,因此我花了挺长时间研究了一下新版本移植的问题,最终终于成功了。

编译完成的库请看我的github项目:FFmpegLibsAndScripts。其中包含了已经完成编译的库和编译的脚本。注意的是iOS版本的库还未实验过。Android已经经过实验并无问题,但仅编译了armv7和arm64的库,如果你要改动脚本为x86编译,可能需要注意asm相关的设置。记住如果需要自己编译,一定要修改脚本中的NDK_HOME变量为你自己的NDK目录。

FFmpeg虽然包含了绝大多数格式的编解码库,但是某些有专利的库并没有包含进去,需要我们手动去链接它。为了实现基本的播放功能,主要需要包含3个库:FDK-AAC(用以解码aac格式是比较先进的压缩格式,如果你仔细看一下大多数的视频格式信息,会发现很多视频的音频部分是以aac格式编码的);mp3lame(用以编解码mp3格式的音频);x264(非常流行的视频编码格式,基本90%的视频目前都是以x264编码的)。首要任务就是编译这三个库。

对于我的编译脚本,我都是放在工程根目录中的。因此运行时请注意位置。输出目录也在根目录的/thin目录中。对于FFmpeg编译时链接的libfdk-aac, libmp3lame以及libx264,都存放在FFmpeg根目录的external-lib目录中,具体如下:

有几个点需要注意。

首先是x264编译出的so库的名称是以libx264.so.1234,其中1234是版本号。显然对于这样的名称,Android是无法识别的,因此我们需要修改x264的configure脚本,其中有这么一段是用来在产生不同平台下库的名称:

if [ "$shared" = "yes" ]; thenAPI=$(grep '#define X264_BUILD' < ${SRCPATH}/x264.h | cut -f 3 -d ' ')if [ "$SYS" = "WINDOWS" -o "$SYS" = "CYGWIN" ]; thenecho "SONAME=libx264-$API.dll" >> config.makif [ $compiler_style = MS ]; thenecho 'IMPLIBNAME=libx264.dll.lib' >> config.makecho "SOFLAGS=-dll -implib:\$(IMPLIBNAME) $SOFLAGS" >> config.makelseecho 'IMPLIBNAME=libx264.dll.a' >> config.makecho "SOFLAGS=-shared -Wl,--out-implib,\$(IMPLIBNAME) $SOFLAGS" >> config.makfielif [ "$SYS" = "MACOSX" ]; thenecho "SOSUFFIX=dylib" >> config.makecho "SONAME=libx264.$API.dylib" >> config.makecho "SOFLAGS=-shared -dynamiclib -Wl,-single_module -Wl,-read_only_relocs,suppress -install_name \$(DESTDIR)\$(libdir)/\$(SONAME) $SOFLAGS" >> config.makelif [ "$SYS" = "SunOS" ]; thenecho "SOSUFFIX=so" >> config.makecho "SONAME=libx264.so.$API" >> config.makecho "SOFLAGS=-shared -Wl,-h,\$(SONAME) $SOFLAGS" >> config.makelseecho "SOSUFFIX=so" >> config.makecho "SONAME=libx264.x.so" >> config.makecho "SOFLAGS=-shared -Wl,-soname,\$(SONAME) $SOFLAGS" >> config.makfiecho 'default: lib-shared' >> config.makecho 'install: install-lib-shared' >> config.mak
fi

最后一个else情况中就是对应我们的情况,我改成了libx264.x.so,不知为何如果直接使用libx264.so会编译失败,所以就改成了这样。这样一来,最后库的名字就是libx264.x.so,同时会生成一个名字为libx264.so的链接。但是即使如此,我们也不能直接使用这个so库去和FFmpeg进行链接,因为在FFmpeg中库的名字是已经写死的,当你设置–enable-x264之后,它只会去找libx264.so。因此我们可以将这个库复制到FFmpeg要链接的目录下之后,再在这个目录中新建一个指向这个库的软链接,只要让这个链接的名字是libx264.so即可。(软链接创建命令:ln -s 源文件 链接)。

另外一个比较坑的地方是fdk-aac的头文件位置。FFmpeg中fdk-aac头文件的包含是这样写的:

#include "fdk-aac/xxx.h"

因此,你在写包含参数(也就是传给编译器的-I参数,表示包含头文件的位置),一定不要直接指向最底层的文件夹,比如你的路径是/a/fdk-aac/xxx.h,你可以写-I/a,但不能写-I/a/fdk-aac,这样FFmpeg是找不到的。

最后写一下关于怎样对编译过程进行debug,一个是多看log文件,对于FFmpeg来说,编译log位置就在ffbuild/config.log,其他的库在出问题时,会提示你去看log并标明log位置。另外一个就是我们主要目标在于configure文件,只要configure没问题,那 编译基本就没问题了。因此在debug阶段,先不要写make & make install,注意看configure的输出,一旦有一个错误,那基本就是跑不过的。configure会产生makefile文件,那是真正用来编译的。如果你上次跑过了,比如为电脑平台编译了FFmpeg,然后又为Android平台编译,如果Android平台configure没有通过,但你仍然还是可以make,因为configure没有成功的话是不会修改makefile文件的,所以你这次make的还是上次电脑平台的目标文件。这点比较迷惑,千万注意。

最新版FFmpeg移植Android:编译so库(基于NDK r20和FFmpeg-4.1.0)相关推荐

  1. FFmpeg学习—android 编译 FDK-AAC 库

    1.编译要求 Ubuntu 14.04 lts 64位 fdk-aac-0.1.4 android-ndk-r12b 2.编译步凑 1.下载fdk-aac 源码: https://nchc.dl.so ...

  2. ffmpeg移植Android方法以及常见问题汇总

    ffmpeg移植Android方法以及常见问题汇总: 1.在ffmpeg官网下载源码包,比如ffmpeg-2.3.在ffmpeg目录下增加Android.mk 和av.mk config.sh三个文件 ...

  3. Android编译Skia库

    Android编译Skia库 本文档提供两种方法编译Skia库 使用aosp源码进行编译 使用skia源码进行编译 两种编译方法都可以编译,并且都可以使用在多个平台中,且可以使用在不同Android版 ...

  4. ijkplayer ffmpeg x264 android 编译

    实测好使, ffmpeg x264 编码器包含,编译了好久, 一直编译不进去,现用 ff3.3–ijk0.8.0–20170518–001 版本的ffmpeg和x264-snapshot-201510 ...

  5. android如何编译lame,Android 编译 Lame 库心路历程

    编译脚本 lame 版本 下载完成后 编译 生成 include lib 两个文件夹 直接拷贝到 lib 目录下 集成 然后 CMakeList 里面添加头文件路径 不做这一步 后面无法在 C++文件 ...

  6. 解决Android编译so库出错问题

    设置中必须进行如下修改 转载于:https://www.cnblogs.com/davidgu/p/4146455.html

  7. android jni 调用java_Android 基于NDK的JNI开发 C调用java和java调用C

    首先,这里所要讲的主要是C调用java的,因为这里网上也没有一个详细的资料,其次,我开发android应用没多久,其中java错误敬请谅解! 关于配置NDK环境问题应该不用再赘述了,这个网上有很多,只 ...

  8. 基于NDK编译Android平台的FFmpeg动态库

    需求 FFmpeg在Linux平台(如Ubuntu)上的支持已经比较完善了,如前述文章介绍 http://blog.csdn.net/ericbar/article/details/73702061, ...

  9. 视频教程-FFmpeg打造Android万能音频播放器-Android

    FFmpeg打造Android万能音频播放器 从事Android移动端开发多年.主导开发过直播.电商.聊天等各种类型APP和游戏SDK:熟悉Android音视频开发.底层NDK开发等:有开源项目:ht ...

最新文章

  1. 使用Silverlight2的WebClient下载远程图片
  2. WCF 改成 restful api
  3. matlab 神经网络预测时间序列示例(水痘模型)
  4. Linux开机启动顺序
  5. 快速写出较好CSS的5种方法
  6. 广西中专机器人应用与维护_我校2018级工业机器人应用与维护专业跟岗实习
  7. 21、 TRUNCATE:清空表记录
  8. 现代计算机三大科学计算,基于三维重建过程中纹理映射问题的研究
  9. 最长公共子序列(JAVA实现)
  10. 移动端向服务端提交数据——实现简单登录
  11. thinkphp python_ThinkPhp 5.0 服务器搭建问题总结
  12. iOS开发-缓存图片到沙盒--思路
  13. 简单多边形三角化(暴力)
  14. Redhat的Linux产品版本AS/ES/WS的联系与区别
  15. 70行Python代码,获取中国数据库大会(DTCC)全部PPT
  16. java加法运算器界面_Java 接口实现计算器加减乘除(字符交互界面)
  17. nivdia错误0x0003_超全解决Geforce 错误代码 ERROR CODE:0x0003问题方法
  18. java paint清空_调用paint方法时Java清除屏幕 – 如何避免?
  19. SVN报Previous operation has not finished; run 'cleanup'
  20. 生成条形码二维码DataMatrix条码.EAN码.39码.交叉25码.UPC码.128码.93码.ISBN码.Codabar等

热门文章

  1. 常用功能测试点汇总(转)
  2. 自定义ContentProvider的一些细节探究
  3. 用VC++实现图像检索技术(转)
  4. JVM 内存区域方面的面试题
  5. 任务47:Identity MVC:ReturnUrl实现
  6. MySQL教程(十一)—— 操作数据表中的记录
  7. SSRS 动态设置分组依据及行组个数
  8. 黑马程序员---java基础-Java之GUI
  9. 如何调节电脑显示屏来保护双眼的小技巧
  10. 检验密码强度的JS类(from thin's blog)