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
是否持续维护 维护中 维护中 维护中

二、分析 ijkPlayer 构建流程

1、 找到ijkplayergithub 主页
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 
export  JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
  • Android SDK(linux):

1)手动下载 sdk-tools-linux-4333796.zip ,也可以通过命令行:
wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip4333796 是最新的了,google 停止更新了

1)手动下载 cmdline-tools 选择 linux 版本,将解压后的目录重命名 cmdline-toolstools ,并将其放在下 $ANDROID_SDK_ROOT/cmdline-tools ,整体路径像:$ANDROID_SDK_ROOT/cmdline-tools/tools详情参考stackoverflower

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"
sudo gedit  /etc/profile 
export ANDROID_NDK=/home/jiong/androidNDK/android-ndk-r14b
export PATH=$ANDROID_NDK:$PATH
3、手动下载 ijkpalyer ,并放到 ubuntu的任意一个目录下。
4、拉取 ijkpalyer JNIffmpeg 代码
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
7、重新跑一下, avi 、asf 、dv都能播放了。
image
8、如果每次都要在 linux 编译出 so ,再移到 android studio 上跑非常麻烦,如何把ijkpalyerjni 源码放到 android studio一键编译。看下面:
  • linux 下观察 jni 文件夹有哪些文件,其中有两个是链接文件(右下角有个箭头),并且三个文件夹都是空文件,没有放置源码在里面。
    image
  • android-ndk-prof 源码在以下文件夹(右键属性,可以看到真实文件的路径)
/ijkplayer-android/android-ndk-profiler-dummy/jni
  • ffmpegso 库文件,以及include 文件夹在以下文件夹(看complie-ffmpeg.sh 的脚本语言打包的输出路径)
/ijkplayer-android/android/contrib/build/ffmpeg-armv7a/output
  • ijkmedia源码在以下文件夹(右键属性,可以看到真实文件的路径)
/ijkplayer-android/ijkmedia
  • 全部拷贝过去,ffmpeg 拷贝 so库以及头文件 过去即可,毕竟ffmpeg 一般不需要二次开发,有bug 等更新就可以,不然每次编译 十几分钟,太长。android-ndk-profiler-dummyijkmedia模块就把源码拷贝过来。 结果位置见下图:

    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 编译起来:
    image
  • 跑起来,大功告成:

image

推荐阅读:Android 编译速度优化黑科技 - RocketX

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容