android jni linux 环境,Android JNI 篇 - 编译 bilibili/ijkPlayer

本篇文章已授权微信公众号 guolin_blog(郭霖)独家发布

一、视频库播放库哪家强

视频播放库

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

是否持续维护

维护中

维护中

维护中

二、分析 ijkPlayer 构建流程

1、 找到ijkplayer 的 github 主页 :

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

看了一下这目录结构,en .... ,果然没看懂,是不是越是庞大的项目,越是喜欢整这些让人摸不着头脑的目录结构要存放代码文件。(其实官方是为了模块化代码结构),那这个要从哪里入手。

2、 先看简介 readme.md ,整理出下面一个流程图

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

三、构建 ijkplayer

按照 readme.md 的流程来

1、 搭建 linux 环境

傻瓜式安装:

2、 搭建 JDK(linux) + Android SDK(linux + NDK(linux)

JDK :

sudo apt-get install openjdk-8-jdk

//配置环境变量:

sudo gedit /etc/profile

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

Android SDK(linux):

2)进入目录 /androidSDK/sdk-tools-linux/tools/bin ,

执行 ./sdkmanager --list 命令看下有哪些目录可以下载:

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

接着拉必要的目录,执行以下命令

./sdkmanager "add-ons;addon-google_apis-google-24" "add-ons;addon-google_apis-google-24" "platform-tools" "platforms;android-28" "tools"

3)配置环境变量

sudo gedit /etc/profile

export ANDROID_SDK=/home/jiong/androidSDK/android-sdk-linux

export PATH=${PATH}:$ANDROID_SDK/tools:$ANDROID_SDK/platform-tools

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

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

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

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

FFmepg

9、编译 ijkplayer jni 代码(依赖ffmpeg库)

cd ..

./compile-ijk.sh all

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

四、迁移 ijkplayer 到 android studio

1、拷贝 编译好的这个 /ijkplayer-android/android 目录,用android studio 导入这个工程(源码4.1G 有点大 )

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

2、看下主要库的大小-- 一共4.8M左右

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

3、跑起来:

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

4、但是结果发现 .avi .dv .asf的视频都不支持

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

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

我们来看一下两者的脚本有哪些不同:左边脚本支持的编码全开(默认),右边脚本,全部先关闭,再开几个支持的。

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

6、重新编译出 ffmpeg

使用全部开启的编译脚本,编译出 so 。46M ,果然够大

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

7、重新跑一下, avi 、asf 、dv都能播放了。

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

8、如果每次都要在 linux 编译出 so ,再移到 android studio 上跑非常麻烦,如何把ijkpalyer 的jni 源码放到 android studio一键编译。看下面:

在linux 下观察 jni 文件夹有哪些文件,其中有两个是链接文件(右下角有个箭头),并且三个文件夹都是空文件,没有放置源码在里面。

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

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模块就把源码拷贝过来。 结果位置见下图:

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

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)

endif

include $(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/include

include $(call all-subdir-makefiles) //找到所有目录下第一层子目录的 android.mk 进行编译

ijkmedia 模块下面的第一层文件夹 凡是有 Android.mk 的,并且里面使用 $(realpath $(LOCAL_PATH)) 的,都要把 $(realpath)去掉。

好了在 android studio 编译起来:

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

跑起来,大功告成:

5aae140956ee?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值