NDK学习笔记:手动编译Android使用的FFmpeg库(Linux)

此文主要是翻查整理当年自己手动编译FFmpeg的记录,之前是在网易云笔记上,现在搬到CSDN上。

 

一、环境配置

开发机windows10 64位,安装xshell+xftp方便与编译机器文件传输和操作通信。官网下载链接,注册的时候是教育自用而非商用。

编译机Ubuntu 14.04.5 LTS,需要安装开始ssh的远程通信协议服务。

问题主要一点,就是xshell链接不上Ubuntu。提示图下图The SSH server rejected your password, Try again.

NDK学习笔记:手动编译Android使用的FFmpeg库(Linux)_第1张图片

初先以为是Ubuntu的SSH服务不正常导致,后来在Linux公社找到方案解决了问题。附带链接。

还有一个小点就是,因为我自己有多台物理机,并没有买云主机,自己安装的Ubuntu其实很多环境问题需要配置的。apt-get指令都需要自己升级,要不然apt-get install会导致了各项依赖包找不到,apt-get更新指令:sudo apt-get update  

关于ubuntu的root超管,默认是没有的,那怎么激活root呢?终端输入:sudo passwd root
输入当前用户的密码进行授权,等到输入新的密码就可以输入root的密码了。这样激活root了。密码慢慢敲,因为终端是不会显示你敲的密码的,连***都不会显示。

 

 

二、准备编译

首先我们需要下载FFmpeg的源码,到官方网站 http://ffmpeg.org/  点击中间显眼的Download跳转到下载页面,然后你会看见更大的Download,这个更大的Download默认是下载最新版的源码资料,但是建议不要用最新的,至于为什么我觉得这是程序员之间默认的规矩吧~哈哈。点击这个更大的Download下方的 More releases,因为公司and自己代码基本都是在用FFmpeg3.3,所以我选择了FFmpeg 3.3.9 "Hilbert" 下载gzip压缩包。

FFmpeg源码库准备好了,我们还需要NDK来进行编译。百度搜索NDK下载,跳转到Google中文官网(https://developer.android.google.cn/ndk/downloads/)还是惯例,不要用最新版。我们找个和FFmeg3.3.9 同期的版本吧。以后有什么隐藏的坑那就以后才算咯。就决定是 Revision 14b (March 2017), 记得下载的是Linux-64版本~

两者都准备好之后,我们打开XShell,以超管root的身份登陆,打开xshell会话中关联的xftp,如下图所示:

NDK学习笔记:手动编译Android使用的FFmpeg库(Linux)_第2张图片

然后把下载回来的 android-ndk-r14b-linux-x86_64.zip 传输到 /user/ndk目录;

把下载回来的 ffmpeg-3.3.9.tar.gz 传输到 /user/ffmpeg目录;

(对应的目录请在xshell命令行中mkdir新建,也可以在xftp的UI中操作,但千万要确保操作的准确性,别乱rm -rf)

 

 

在正式编译前,记录一下vim的一些配置:

命令行下输入vim  /etc/vim/vimrc 进入vim的系统配置,滚到最下放空白处追加如下:(不包括 //注释)

set nu //行号
set tabstop //首行缩进
set cursorline //高亮显示
set ruler //右下角显示光标位置
ok! shift + wq

三、正式编译

第一步,先配置NDK:

我们先对ndk的目录赋于权限:chmod 777 -R ndk

因为我们下载的ndk是zip格式,我们先解压:unzip  android-ndk-r14b-linux-x86_64.zip

解压完成之后,我们要配置ndk目录到系统的环境变量中,在命令行输入:vim ~/.bashrc

之后按 i 进入输入模式之后,到文件最下方添加如下:
export NDKROOT=/usr/ndk/android-ndk-r14b
export PATH=$NDKROOT:$PATH
esc退出输入模式,shift + wq 保存退出。
退回到命令行之后,source ~/.bashrc 执行更新一下新的环境变量。

 

第二步,配置ffmpeg:

我下载的ffmpeg是ffmpeg-3.3.9.tar.gz格式,所以还是要先解压:tar -zxvf ffmpeg-3.3.9.tar.gz 

解压结束后,我们可以看到如下目录和文件:

NDK学习笔记:手动编译Android使用的FFmpeg库(Linux)_第3张图片

下一步也是最关键的一步了:编译脚本 build_android.sh

以下放出我自己从网上找回来的可用脚本,是编译完整ffmpeg,没有进行多余的裁剪。

#!/bin/bash
make clean
export NDK=/usr/ndk/android-ndk-r14b
export SYSROOT=$NDK/platforms/android-9/arch-arm/
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
export CPU=arm
export PREFIX=$(pwd)/android/$CPU
export ADDI_CFLAGS="-marm"

./configure --target-os=linux \
--prefix=$PREFIX --arch=arm \
--disable-doc \
--enable-shared \
--disable-static \
--disable-yasm \
--disable-symver \
--enable-gpl \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install

以上编译选项基本都比较容易,难懂的我也不太会。详尽的编译选项我们可以在命令行的ndk目录下输入:./configure --help

保存build_android.sh xftp传送到编译机器Ubuntu的/usr/ffmpeg/ffmpeg-3.3.9/下,开始我们的排坑之旅:

root@zhaozhirong-X55VDR:/usr/ffmpeg/ffmpeg-3.3.9# ./build_android.sh
-bash: ./build_android.sh: 权限不够

这个比较好解决:chmod 777 build_android.sh

root@zhaozhirong-X55VDR:/usr/ffmpeg/ffmpeg-3.3.9# ./build_android.sh
Makefile:2: config.mak: 没有那个文件或目录
Makefile:67: /common.mak: 没有那个文件或目录
Makefile:114: /libavutil/Makefile: 没有那个文件或目录
Makefile:114: /library.mak: 没有那个文件或目录
Makefile:116: /doc/Makefile: 没有那个文件或目录
Makefile:206: /tests/Makefile: 没有那个文件或目录
make: *** 没有规则可以创建目标“/tests/Makefile”。 停止。
Unknown option "".
See ./configure --help for available options.
./build_android.sh: 行 11: --prefix=/usr/ffmpeg/ffmpeg-3.3.9/android/arm: 没有那个文件或目录
./build_android.sh: 行 13: --disable-doc: 未找到命令
Makefile:2: config.mak: 没有那个文件或目录
Makefile:67: /common.mak: 没有那个文件或目录
Makefile:114: /libavutil/Makefile: 没有那个文件或目录
Makefile:114: /library.mak: 没有那个文件或目录
Makefile:116: /doc/Makefile: 没有那个文件或目录
Makefile:206: /tests/Makefile: 没有那个文件或目录
make: *** 没有规则可以创建目标“/tests/Makefile”。 停止。
Makefile:2: config.mak: 没有那个文件或目录
Makefile:67: /common.mak: 没有那个文件或目录
Makefile:114: /libavutil/Makefile: 没有那个文件或目录
Makefile:114: /library.mak: 没有那个文件或目录

然后可能会出现这样的错误,这啥玩意啊?

此时我们就要检查一番 sh脚本是否有细节的坑了。

几点经验总结:(偷偷告诉你,上面的sh是有错误的)

  1. export等路径一定要检查仔细是否真实存在
  2.  ./configure 后面跟的编译选项,每个选项中间间隔一个空格,不要多不要少,而且换行符 \ 只起到换行的作用,别强迫症发作又多加个空格!
  3. 额外参数--extra 一定一定要查阅configure --help (/usr/ffmpeg/ffmpeg-3.3.9/configure是可以直接vim打开的)

以上就是我自己总结出来的注意事项,仔细修改之后,再次执行 ./build_android.sh

 

build_android.sh  /bin/bash^M: 坏的解释器:没有那个文件或目录。

如果出现此错误,是因为 .sh文件是从windows拷贝过来的,所以多了\r,执行:sed -i 's/\r$//' build_android.sh     或者:

root@zhaozhirong-X55VDR:/usr/ffmpeg/ffmpeg-3.3.9# apt-get install dos2unix
root@zhaozhirong-X55VDR:/usr/ffmpeg/ffmpeg-3.3.9# dos2unix build_android.sh 
dos2unix: converting file build_android.sh to Unix format ...

 

 

root@zhaozhirong-X55VDR:/usr/ffmpeg/ffmpeg-3.3.9# ./build_android.sh
Makefile:2: config.mak: 没有那个文件或目录
Makefile:67: /common.mak: 没有那个文件或目录
Makefile:114: /libavutil/Makefile: 没有那个文件或目录
Makefile:114: /library.mak: 没有那个文件或目录

如果出现以上之后,卡住不动了,恭喜你!不要着急再等等,不出10s,编译就正常跑起来了。

 

四、修改编译配置

编译之后还没结束。我们可以跑到ffmpeg-3.3.9目录下多了android的一个目录。之后看到里面的编译产物,如下图:

NDK学习笔记:手动编译Android使用的FFmpeg库(Linux)_第4张图片

你可能看到你想要的lib***.so在其中,但我想告诉你的是,此so非你想要的so。

通过ls -l 指令列出的详细信息可以看到lib***.so都指向了lib***.so.*.*.100文件,正式的库其实就是这些带详细版本后缀的文件

你可能会说,手动更改把版本数字编号删除。我想说的是,这貌似可行,但是有什么奇葩的情况,请不要私信我。

那怎么办呢?

vim打开 /usr/ffmpeg/ffmpeg-3.3.9/下的configure,找到 # build settings 如下所示:

# build settings
SHFLAGS='-shared -Wl,-soname,$$(@F)'
LIBPREF="lib"
LIBSUF=".a"
FULLNAME='$(NAME)$(BUILDSUF)'
LIBNAME='$(LIBPREF)$(FULLNAME)$(LIBSUF)'
SLIBPREF="lib"
SLIBSUF=".so"
SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)'
SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)'
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'

 按如下修改:MAJOR的命名规则修改一下,关键的SLIB_INSTALL_NAME指向我们想要的lib***。so,其余两个major和version就换成LINKS就ojbk了!

#SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
#LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
#SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
#SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
# Zzr
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME_WITH_VERSION)'

记得删除/usr/ffmpeg/ffmpeg-3.3.9/android 再重新 ./build_android.sh 哦。

 

至此,Android-NDK使用的 FFmpeg八大模块so已经编译成功。o(* ̄▽ ̄*)ブ

你可能感兴趣的:(NDK学习笔记)