Android|Android JNI 篇 - 编译 bilibili/ijkPlayer
本篇文章已授权微信公众号 guolin_blog(郭霖)独家发布
一、视频库播放库哪家强
二、分析 ijkPlayer 构建流程
三、构建 ijkplayer
四、迁移 ijkplayer 到 android studio
一、视频库播放库哪家强
视频播放库 | bilibili/ijkplayer | google/ExoPlayer | VLC-Android |
---|---|---|---|
支持ffmpeg拓展 | 支持 | 不支持 | 嵌入ffmpeg 的 libavcodec库 |
可拓展性 | 高 | 无 | 低,需要二次开发 |
体积大小 | 5M-45M | 无体积 | 13M |
播放的视频格式 | 只要ffmpeg支持都支持 | 支持手机支持播放的 | 大多数易见视频 |
start | 2.1W | 1.2W | GitLab 296个 |
issue | 2116 Open / 2318 Close | 201 Open / 4389 Close | Open 169/Closed 544 |
是否持续维护 | 维护中 | 维护中 | 维护中 |
1、 找到
ijkplayer
的 github
主页 : 文章图片
image
看了一下这目录结构,en .... ,果然没看懂,是不是越是庞大的项目,越是喜欢整这些让人摸不着头脑的目录结构要存放代码文件。(其实官方是为了模块化代码结构),那这个要从哪里入手。2、 先看简介
readme.md
,整理出下面一个流程图 文章图片
image 三、构建 ijkplayer
按照 readme.md 的流程来
1、 搭建
linux
环境
傻瓜式安装:下载Ubuntu
下载VMWare
2、 搭建
JDK(linux)
+ Android SDK(linux
+ NDK(linux)
-
JDK
:
sudo apt-get install openjdk-8-jdk
//配置环境变量:
sudo gedit/etc/profile
exportJAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
-
Android SDK(linux)
:
wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
,4333796
是最新的了,google
停止更新了1)手动下载 cmdline-tools 选择
linux
版本,将解压后的目录重命名 cmdline-tools
为 tools
,并将其放在下 $ANDROID_SDK_ROOT/cmdline-tools
,整体路径像:$ANDROID_SDK_ROOT/cmdline-tools/tools
,详情参考stackoverflower【Android|Android JNI 篇 - 编译 bilibili/ijkPlayer】2)配置环境变量
sudo gedit/etc/profile
export ANDROID_SDK_ROOT=/home/jiong/androidSDK/android-sdk-linux
export PATH=$PATH:$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/cmdline-tools/tools/bin
3)进入目录
/androidSDK/sdk-tools-linux/tools/bin
,执行
./sdkmanager --list
命令看下有哪些目录可以下载:文章图片
image
接着拉必要的目录,执行以下命令
./sdkmanager "add-ons;
addon-google_apis-google-24" "add-ons;
addon-google_apis-google-24""platform-tools" "platforms;
android-28" "tools"
- 下载 android-ndk-r14b-linux-x86_64.zip
sudo gedit/etc/profile
export ANDROID_NDK=/home/jiong/androidNDK/android-ndk-r14b
export PATH=$ANDROID_NDK:$PATH
3、手动下载 ijkpalyer ,并放到
ubuntu
的任意一个目录下。
4、拉取 ijkpalyer JNI
和 ffmpeg
代码
cd ijkplayer-android
./init-android.sh
5、拉取
openssl
代码
./init-android-openssl.sh
6、编译
openssl
代码
cd android/contrib
./compile-openssl.sh clean
./compile-openssl.sh all
文章图片
image 7、选择配置
ffmpeg
信息
cd ../../
cd config
rm module.sh
ln -s module-lite.sh module.sh
//如果需要支持更多的视频格式用下面的配置
// ln -s module-default.sh module.sh
8、编译
ffmpeg
代码
cd ../
cd android/contrib
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
文章图片
FFmepg 9、编译
ijkplayer jni
代码(依赖ffmpeg
库)
cd ..
./compile-ijk.sh all
文章图片
image 四、迁移 ijkplayer 到 android studio
1、拷贝 编译好的这个
/ijkplayer-android/android
目录,用android studio
导入这个工程(源码4.1G 有点大 ) 文章图片
image
文章图片
image 2、看下主要库的大小-- 一共
4.8M
左右 文章图片
image 3、跑起来: image 4、但是结果发现
.avi .dv .asf
的视频都不支持 image 5、修改 ffmpeg
的参数
//这里的配置换成下面的配置参数,这里是 linux 软引用表示 module.sh 文件名,代表了module-default.sh 文件
//ln -s module-lite.sh module.sh
ln -s module-default.sh module.sh
编译
ffmpeg
脚本do-compile-ffmpeg.sh
文件里面有这么一句代码:export COMMON_FF_CFG_FLAGS=.$FF_BUILD_ROOT/../../config/module.sh
- 我们来看一下两者的脚本有哪些不同:左边脚本支持的编码全开(默认),右边脚本,全部先关闭,再开几个支持的。
文章图片
image 6、重新编译出
ffmpeg
- 使用全部开启的编译脚本,编译出 so 。46M ,果然够大
文章图片
image
avi 、asf 、dv
都能播放了。 image 8、如果每次都要在 linux
编译出 so
,再移到 android studio
上跑非常麻烦,如何把ijkpalyer
的jni
源码放到 android studio
一键编译。看下面:
- 在
linux
下观察jni
文件夹有哪些文件,其中有两个是链接文件(右下角有个箭头),并且三个文件夹都是空文件,没有放置源码在里面。
文章图片
image -
android-ndk-prof
源码在以下文件夹(右键属性,可以看到真实文件的路径)
/ijkplayer-android/android-ndk-profiler-dummy/jni
-
ffmpeg
的so
库文件,以及include
文件夹在以下文件夹(看complie-ffmpeg.sh
的脚本语言打包的输出路径)
/ijkplayer-android/android/contrib/build/ffmpeg-armv7a/output
-
ijkmedia
源码在以下文件夹(右键属性,可以看到真实文件的路径)
/ijkplayer-android/ijkmedia
- 全部拷贝过去,
ffmpeg
拷贝so
库以及头文件 过去即可,毕竟ffmpeg
一般不需要二次开发,有bug
等更新就可以,不然每次编译 十几分钟,太长。android-ndk-profiler-dummy
和ijkmedia
模块就把源码拷贝过来。 结果位置见下图:
文章图片
image
- 接下来需要修改
/jni/Android.mk
,不然编译不过去:
旧代码
LOCAL_PATH := $(call my-dir)MY_APP_JNI_ROOT := $(realpath $(LOCAL_PATH))
MY_APP_PRJ_ROOT := $(realpath $(MY_APP_JNI_ROOT)/..)
MY_APP_ANDROID_ROOT := $(realpath $(MY_APP_PRJ_ROOT)/../../../..)ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-armv7a/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endif
ifeq ($(TARGET_ARCH_ABI),armeabi)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-armv5/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endif
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-arm64/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endif
ifeq ($(TARGET_ARCH_ABI),x86)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-x86/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endif
ifeq ($(TARGET_ARCH_ABI),x86_64)
MY_APP_FFMPEG_OUTPUT_PATH := $(realpath $(MY_APP_ANDROID_ROOT)/contrib/build/ffmpeg-x86_64/output)
MY_APP_FFMPEG_INCLUDE_PATH := $(realpath $(MY_APP_FFMPEG_OUTPUT_PATH)/include)
endifinclude $(call all-subdir-makefiles)
由于
jni
需要使用相对路径 ,去掉$(realpath)
,这里只保留armeabi-v7a
改成:LOCAL_PATH := $(call my-dir)
MY_APP_ANDROID_ROOT := $(LOCAL_PATH)MY_APP_FFMPEG_OUTPUT_PATH :=$(MY_APP_ANDROID_ROOT)/ffmpeg/lib
MY_APP_FFMPEG_INCLUDE_PATH :=$(MY_APP_ANDROID_ROOT)/ffmpeg/includeinclude $(call all-subdir-makefiles) //找到所有目录下第一层子目录的 android.mk 进行编译
-
ijkmedia
模块下面的第一层文件夹 凡是有Android.mk
的,并且里面使用$(realpath $(LOCAL_PATH))
的,都要把$(realpath)
去掉。 - 好了在
android studio
编译起来:
image - 跑起来,大功告成:
推荐阅读
- android第三方框架(五)ButterKnife
- 2018年11月19日|2018年11月19日 星期一 亲子日记第144篇
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- 拍照一年啦,如果你想了解我,那就请先看看这篇文章
- Android中的AES加密-下
- 亲子日记第186篇,2018、7、26、星期四、晴
- 带有Hilt的Android上的依赖注入
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 两短篇
- android|android studio中ndk的使用