特此完整记录一下。操作时一定要 注意路径 注意路径 注意路径 重要的事情说三遍!
本次编译所用的环境以及所使用的工具:
系统版本(虚拟机):Ubuntu14.04 LTS 64位
NDK版本:R17C Linux 64位
FFmpeg版本:4.1.3.tar.bz2
本次使用工具下载地址:
系统下载地址: https://pan.baidu.com/s/1DPWtEtWDi56-eN8srZA-mg 提取码:ojo9
NDK下载地址: https://pan.baidu.com/s/17w2xyhoEcixYy_JN1OBbBw 提取码:sk9y
FFmpeg下载地址: https://pan.baidu.com/s/1yGkPBTCvg307lgMIbdVfjQ 提取码:owkw
官方下载地址:
系统下载地址: https://www.ubuntu.com/download/desktop
NDK下载地址: https://developer.android.google.cn/ndk/downloads
FFmpeg下载地址: http://ffmpeg.org/download.html
准备工作:
安装系统,配置环境,解压好NDK以及FFMPEG
NDK解压:拉到指定目录下。cd 进去NDK压缩包所在的目录,
unbuntu .zip后缀的解压方法: unzip 文件名;
. tar.xx后缀的解压方法: tar -xvf 文件名;
首先基本环境安装: 以下三条命令直接一条一条Copy到终端命令运行 等待完成
sudo apt-get update
sudo apt-get install gcc
sudo apt-get -y --force-yes install autoconf automake build-essential libass-dev libfreetype6-dev \
libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev \
libxcb-xfixes0-dev pkg-config texi2html zlib1g-dev
NDK环境配置:
打开终端(即虚拟机命令行) 输入 sudo su 输入密码 出现ROOT字样 代表取得最高权限
依次输入 cd / cd /etc vi profile
输入vi profile后出现 光标移动到最后增加红框的系统变量。
输入 按ESC 退出编辑模式 输入“:wq” 就保存退出了 ":q"为退出不保存 :是符号
输入 source /etc/profile 读取并执行当前环境
接着 cd / 回到主目录 echo $NDK_HOME 输出路径是否正确
输入 $NDK_HOME/ndk-build -version 查看是否配置完成;成功如下 会输出NDK的信息
至此NDK环境搭建完成!
开始编译:
解压FFmpeg:
进入解压文件夹 打开FFmpeg源码文件下的configure找到
修改成
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_LINKS='$(SLIBNAME)'
保存关闭
命令行进入 FFmpeg源码解压的文件夹 先执行编译一次FFmpeg再编译.SO库 不然后面会出现许多找不到文件奇奇怪怪的错误
输入 ./configure 完成配置,等待完成后输入make 开始编译
等编译完,时间大概10-20分钟。看个人电脑配置。最后输入make install 等待完成
现在开始编译Android用的.SO库。
进入FFmpeg目录 新创建一个 build.sh 文件
打开 build.sh文件编写脚本
如下:这是一个完整FFmpeg类库功能的脚本(完整编译完挺大的)
#!/bin/bash
set -x
API=14
NDK=/home/zgk/android-ndk-r17c
SYSROOT=$NDK/platforms/android-$API/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function function_one
{
./configure \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-ffmpeg \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-I$NDK/sysroot/usr/include/arm-linux-androideabi -isysroot $NDK/sysroot -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm -march=armv7-a" \
--enable-neon
make clean all
make
make install
}
CPU=armv7-a
PREFIX=$(pwd)/android/$CPU
function_one
注意去掉代码里面的空格。文本编辑器会留空格
如果嫌弃库太大,而且又不需要那么多功能,可以进入到FFmpeg源码目录下 使用 ./configure --help 命令来查看要启用或禁用哪些功能,只编译自己所需要的功能
帮助选项译文: --help打印此消息 --quiet抑制显示信息输出 --list-decoders显示所有可用的解码器 --list-encoders显示所有可用的编码器 --list-hwaccels显示所有可用的硬件加速器 --list-demuxers显示所有可用的解复用器 --list-muxers显示所有可用的复用器 --list-parsers显示所有可用的解析器 --list-protocols显示所有可用的协议 --list-bsfs显示所有可用的比特流过滤器 --list-indevs显示所有可用的输入设备 --list-outdevs显示所有可用的输出设备 --list-filters显示所有可用的过滤器
标准选项: --logfile = FILE日志测试并输出到FILE [ffbuild / config.log] --disable-logging不记录配置调试信息 - 如果生成任何配置警告,则-fatal-warnings将失败 --prefix = PREFIX安装在PREFIX [/ usr / local] --bindir = DIR在DIR [PREFIX / bin]中安装二进制文件 -datadir = DIR在DIR中安装数据文件[PREFIX / share / ffmpeg] --docdir = DIR中的DIR安装文档[PREFIX / share / doc / ffmpeg] --libdir = DIR在DIR [PREFIX / lib]中安装库 --shlibdir = DIR在DIR [LIBDIR]中安装共享库 --incdir = DIR安装包含在DIR [PREFIX / include]中 -mandir = DIR在DIR安装手册页[PREFIX / share / man] --pkgconfigdir = DIR在DIR [LIBDIR / pkgconfig]中安装pkg-config文件 --enable-rpath使用rpath允许在路径中安装库 不属于动态链接器搜索路径的一部分 链接程序时使用rpath(USE WITH CARE) --install-name-dir =已安装目标的DIR Darwin目录名
许可选项: --enable-gpl允许使用GPL代码,生成的库 和二进制文件将在GPL下[no] --enable-version3升级(L)GPL到版本3 [no] --enable-nonfree允许使用非自由代码,生成的库 和二进制文件将是不可分发的[不]
配置选项: --disable-static不构建静态库[no] --enable-shared构建共享库[no] --enable-small优化尺寸而不是速度 --disable-runtime-cpudetect禁用在运行时检测CPU功能(较小的二进制) --enable-grey启用全灰度支持(较慢的颜色) --disable-swscale-alpha禁用swscale中的alpha通道支持 --disable-all禁用构建组件,库和程序 --disable-autodetect禁用自动检测到的外部库[no]
计划选项: --disable-programs不构建命令行程序 --disable-ffmpeg禁用ffmpeg构建 --disable-ffplay禁用ffplay构建 --disable-ffprobe禁用ffprobe构建
文档选项: --disable-doc不构建文档 --disable-htmlpages不构建HTML文档页面 --disable-manpages不构建man文档页面 --disable-podpages不构建POD文档页面 --disable-txtpages不构建文本文档页面
组件选项: --disable-avdevice禁用libavdevice构建 --disable-avcodec禁用libavcodec构建 --disable-avformat禁用libavformat构建 --disable-swresample禁用libswresample build --disable-swscale禁用libswscale构建 --disable-postproc禁用libpostproc构建 --disable-avfilter禁用libavfilter构建 --enable-avresample启用libavresample build(不建议使用)[no] --disable-pthreads禁用pthreads [autodetect] --disable -w32threads禁用Win32线程[autodetect] --disable-os2threads禁用OS / 2线程[autodetect] --disable-network禁用网络支持[否] --disable-dct禁用DCT代码 --disable-dwt禁用DWT代码 --disable-error-resilience禁用错误恢复代码 --disable-lsp禁用LSP代码 --disable-lzo禁用LZO解码器代码 --disable-mdct禁用MDCT代码 --disable-rdft禁用RDFT代码 --disable-fft禁用FFT代码 --disable-faan禁用浮点AAN(I)DCT代码 --disable-pixelutils禁用libavutil中的pixel utils
个别组件选项: --disable-everything禁用下面列出的所有组件 --disable-encoder = NAME禁用编码器NAME --enable-encoder = NAME启用编码器NAME --disable-encoders禁用所有编码器 --disable-decoder = NAME禁用解码器NAME --enable-decoder = NAME启用解码器NAME --disable-decoders禁用所有解码器
保存关闭;
输入 chmod 777 build.sh 给刚刚新建的文件可执行权限
输入 ./build.sh 开始编译SO库 如图 即是开始编译了。接下来耐心等待 时间看个人电脑配置,大概10几20分钟
编译完成不出意外的话,我们就可以在FFmpeg源码目录下找到android的文件夹了
我编译期间出现三个坑的解决办法 (NDK版本问题。如果出现其他解决不了的错误尝试更换NDK版本)
libavcodec/aaccoder.c: In function 'search_for_ms': libavcodec/aaccoder.c:803:25: error: expected identifier or '(' before numeric constant int B0 = 0, B1 = 0;
这个错误似乎是定义变量冲突导致的,
解决办法:修改libavcodec/aaccoder.c 文件 B0改成b0,其实就是变量名冲突了,把int类型的变量换个变量名
libavcodec/hevc_mvs.c: In function 'derive_spatial_merge_candidates': libavcodec/hevc_mvs.c:208:15: error: 'y0000000' undeclared (first use in this function) ((y ## v) >> s->ps.sps->log2_min_pu_size))
同上
解决方法:将libavcodec/hevc_mvs.c文件的变量B0改成b0,xB0改成xb0,yB0改成yb0
libavcodec/opus_pvq.c: In function 'quant_band_template': libavcodec/opus_pvq.c:498:9: error: expected identifier or '(' before numeric constant int B0 = blocks;
同上
解决方法:将libavcodec/opus_pvq.c文件的变量B0改成b0