接着之前的一篇简要的ijkplayer的编译过程,这一遍主要是详细描述ijkplayer编译的详细过程,跟着编译的脚本详细分析在ijkplayer从开源库的clone到完整地编译android共享库的过程。
下载最新版的源码
|
|
init-android.sh 下载编译所需的库
这一步会用到tools文件夹下面的工具脚本,
pull ffmpeg base
pull-repo-base.sh,将ffmpeg源码clone到extra/ffmpeg文件夹,1sh pull-repo-bash.sh https://github.com/Bilibili/FFmpeg.git extra/ffmpeg
pull-repo-base.sh脚本
简化一下,就是
pull ffmpeg fork
将上一步clone下来的ffmpeg源码,不同arm处理器架构的(armv5 armv7 arm64 x86 x86_64)的文件相应文件夹下面android/contrib/,
pull-repo-ref.sh脚本
简化一下(以arm64为例),
--reference的作用就是会clone之前上一步的仓库缓存,达到节省不必要的clone时间,
init-config.sh
|
|
这一步是配置编译ffmpeg的参数,配置文件我们可以自己编写,config/文件夹下面有已经预设的,module-defualt.sh是ffmpeg官方默认的编译参数,module-lite.sh包含通用的编译参数,module-lite-hevc.sh在通用的基础之上添加了hevc解码,也就是俗称的H265
init-android-libyuv.sh
|
|
下载libyuv的库,简单来表述就是:
compile-ffmpeg.sh 编译ijkffmpeg.so共享库
首先清除源码中可能存在的编译缓存
然后开始编译ffmpeg
compile-ffmepg.sh后面的参数代表编译哪个arm建构的版本,默认编译armv7a,编译选项,后面执行的compile-ijk.sh后面的选项也是同样的道理。
|
|
编译的过程中,
check archs
确认编译的相应处理器架构版本
例如会汇编armv7a,输出的确认信息如下:
执行do-pcompile-ffmeg.sh
开始执行编译,脚本路径:android/contrib/tools/do-compile-ffmepg.sh
以编译arm64为例,简要表述这一步,
check env
这一步会检测,我们执行编译脚本compile-ijk.sh时,有没有添加all armv5 armv7a arm64 x86 x86_64等选项,否则会提醒:You must specific an architecture 'arm, armv7a, x86, ...
make NDK standalone toolchain
这一步调用tools/do-detect-env.sh,脚本路径:android/contrib/tools/do-detect-env.sh
检测编译环境,用于检测NDK是否在环境变量中存在,包括NDK中的gcc版本和arm-linux-androideabi的版本,
会添加一些编译的参数,这里我们会关注一个编译参数,FF_CFG_FLAGS:编译ffmpeg添加的额外的参数(config/module.sh中已经添加了一部分参数),FF_PREFIX编译之后输出的文件目录,例如arm64输出目录是:android\contrib\build\ffmpeg-arm64\output
check ffmpeg env
这一步加载fffmpeg的配置文件,这个文件就是我们之前配置的init-config.sh中配置的文件
configurate ffmpeg
这一步是配置ffmepg的编译参数,脚本代码块如下:
FF_CFG_FLAGS就是前两步配置的编译参数。
compile ffmpeg
这一步是编译正式开始编译ffmpeg,脚本代码如下:
|
|
这一步之后就完成了FFmpeg的编译过程,cp config.* $FF_PREFIX这一字段,就是在编译之前,把我们的编译的配置信息log都被复制到了相应的moudle文件夹,路径:android/contrib/build/ffmpeg-arm64/output/



link ffmpeg
关键的一步来了,正常情况下,我们编译出来的ffmpeg的包含有libavcodec.a libavfilter.a libavformat.a libavutil.a libswresample.a libswscale.a,这六个输出库,ijkplayer
将这六个库编译成一个独立ijkplayer.so的共享库,
以编译arm64版本为例,
create files for shared ffmpeg
这一步将生成的库文件拷贝到相应的共享文件夹,
mysedi()函数中注意几个命令的使用方法:bansename $f表示去掉文件f的路径和后缀名;sed表示查找替换功能,sed 's/\output/\/output\/shared/g'是将/output/替换成/output/shared/
这一步之后完成了对ffmpeg的编译,并且通过android的standalone-toolchain编译完成了ffmpeg的共享库-libijkffmpeg.so
开始编译ijkplayer.so共享库
|
|
这一步进入ijkplayer/下相应版本的文件夹下面执行ndk-build命令,将打包编译生成ijkplayer.so,ndk-build命令将打包编译三部分的源码:ffmepg:之前打包编译的SRC_FILES:ijkffmpeg.so,ffmepg的includeandroid-ndk-prof:编译ijkprof中的c源码,生成android-ndk-profiler的静态库,主要作用的打印ndk-build的log信息。ijkmedia:编译ijkmedia/下面的源码,其中主要包括了ijk4a,jkplayer,ijksdl,ijksoundtouch,ijkyuv这5个模块
这一步完成之后,ndk根据上面列出的模块下面的Android.mk文件进行编译,最后生成ijkplayer的共享库