前言
ijkplayer作为业界最有名的播放器开源项目,理论上说可能很多方面都已经做得很优秀了。我们直接拿来用不就完事了吗?为什么还要进行二次开发,这不是自己给自己挖坑吗?
本着只有更优没有最优的原则,ijkplayer也存在这很多需要优化的地方,比如我们在《音视频面试基础题》中提到的直播秒开优化
方案,对于基于ffmpeg的函数avformat_find_stream_info
函数的调用问题就需要我们对ijkplayer进行修改。
又比如我们在使用ijkplayer播放音视频的过程中遇到了问题就可能需要对ijkplayer进行调试,这时候也需要将ijkplayer导入AS工程中才能调试。甚至一些公司更加业务需求,可能需要对ijkplayer进行一些定制化的需求,这些都需要对ijkplayer进行二次开发。
笔者在对ijkplayer进行二次开发的时候也是踩了不少坑,查了不少资料才把坑给填了,今天把它分享出来,算作一个记录。
废话不多说,直接开杠
这里说一下笔者使用的Android Studio版本是3.51,使用的NDK版本是NDKr16
首先我们按照《ijkplayer编译实践》中所说的下载好ijkplayer的源码并编译好之后,
将android/ijkplayer
目录导入到AS中,导入之后我们发现并不能编译通过。
按照官方的指引如果我们想要对ijkplayer进行调试则需要在ijkplayer的源码目录下面运行一下这句命令:
代码语言:javascript复制sh android/patch-debugging-with-lldb.sh armv7a
运行这条命令之后我们发现报错了:
代码语言:javascript复制patch apply ==> armv7a
git apply ==> patches/0001-gitignore-ignore-.externalNativeBuild.patch
git apply ==> patches/0002-gradle-upgrade-build-tool-to-2.2.0-beta2.patch
error: patch failed: android/ijkplayer/ijkplayer-example/build.gradle:44
error: android/ijkplayer/ijkplayer-example/build.gradle: patch does not apply
git apply ==> patches/0003-armv7a-enable-debugging-with-LLDB.patch
error: patch failed: ijkmedia/ijkplayer/Android.mk:59
error: ijkmedia/ijkplayer/Android.mk: patch does not apply
error: patch failed: ijkmedia/ijksdl/Android.mk:70
error: ijkmedia/ijksdl/Android.mk: patch does not apply
git apply ==> patches/0004-armv7a-link-prebuilt-staic-libraries-of-ffmepg.patch
这是因为这个脚本是用git一些修改patch进行代码还原,但是由于这个脚本已经太久没有更新了,而ijkplayer的一些代码结构又有调整导致脚本无法从patch文件附带的这些信息把代码正确还原回去。
我们通过分析android/patch-debugging-with-lldb.sh
这个脚本文件之后发现,这个脚本主要是针对4个patch文件进行git代码还原。
而这四个patch文件就是:
代码语言:javascript复制android/patches/0001-gitignore-ignore-.externalNativeBuild.patch
android/patches/0002-gradle-upgrade-build-tool-to-2.2.0-beta2.patch
android/patches/0003-$PARAM_TARGET-enable-debugging-with-LLDB.patch
android/patches/0004-$PARAM_TARGET-link-prebuilt-staic-libraries-of-ffmepg.patch
我们任意打开一个pathc文件看看,比如android/patches/0002-gradle-upgrade-build-tool-to-2.2.0-beta2.patch
这个文件:
From 5d70fa0496f9ebfbcfa3786d85c74c690d66781e Mon Sep 17 00:00:00 2001
From: ctiao <calmer91@gmail.com>
Date: Mon, 29 Aug 2016 14:50:34 0800
Subject: [PATCH 2/2] gradle: upgrade build-tool to 2.2.0-rc1
---
android/ijkplayer/build.gradle | 2 -
1 file changed, 1 insertion( ), 1 deletion(-)
diff --git a/android/ijkplayer/build.gradle b/android/ijkplayer/build.gradle
index 0de03ec..6132c1d 100644
--- a/android/ijkplayer/build.gradle
b/android/ijkplayer/build.gradle
@@ -5,7 5,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.1.3'
classpath 'com.android.tools.build:gradle:2.2.0-rc1'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7'
--
2.7.4 (Apple Git-66)
有过git使用经验的童鞋都知道行前的
和-
的意思,简单来说
代表增加了这些内容,-
删除了这行内容。
按照这个规则,我们通过分析这4个patch文件进行手动还原代码大概就能使工程运行起来,但是可能会因为gradle的版本太老可能会导致失败。
下面说下笔者的主要修改:
1、 将其他的非armv7a的cpu架构的库删掉或者注释
修改文件ijkplayer/setting.gradle
:
//include ':ijkplayer-armv5' ':ijkplayer-x86_64'
include ':ijkplayer-armv7a'
//include ':ijkplayer-arm64'
//include ':ijkplayer-x86'
include ':ijkplayer-java'
//include ':ijkplayer-exo'
include ':ijkplayer-example'
2、 升级工程的gradle版本
对于怎么获取最新的gradle版本,笔者在这说一个技巧,首先我们使用Android Studio新建一个新的可运行项目。
然后将项目根目录下的build.gradle
下的classpath
这行拷贝到ijkpalyer根项目的build.gradle
的相应位置,笔者这里使用的是classpath 'com.android.tools.build:gradle:3.5.1'
;
第二步将新建的项目的gradle/wrapper/gradle-wrapper.properties
文件拷贝到ijkplayer项目的对应目录完成替换即可。
3、 修改ijkplayer-armv7a工程关联Android.mk编译脚本
修改文件:ijkplayer/ijkplayer-armv7a/build.gradle
:
不要指定jni的lib库文件夹位置:
代码语言:javascript复制android {
//删除以下内容
//sourceSets.main {
// jniLibs.srcDirs 'src/main/libs'
// jni.srcDirs = [] // This prevents the auto generation of Android.mk
//}
}
添加native代码主编译脚本Android.mk的文件路径:
代码语言:javascript复制android {
//添加以下内容
externalNativeBuild {
ndkBuild {
path "src/main/jni/Android.mk"
}
}
}
设置编译脚本的参数:
代码语言:javascript复制android {
defaultConfig {
//添加以下内容
externalNativeBuild {
ndkBuild {
arguments "NDK_APPLICATION:=src/main/jni/Application.mk"
abiFilters "armeabi-v7a"
}
}
}
}
开启工程的debug模式:
代码语言:javascript复制android {
buildTypes {
//添加以下内容
debug {
debuggable true
jniDebuggable true
ndk {
debuggable true
}
}
}
}
4、 修改ijkplayer-example
的build.gradle
修改文件:ijkplayer/ijkplayer-example/build.gradle
:
删除渠道配置:
代码语言:javascript复制// 注释掉这个,因为在某些gradle版本上会报Flavors纬度不一致的错误
// productFlavors {
// all32 { minSdkVersion 9 }
// all64 { minSdkVersion 21 }
// // armv5 {}
// // armv7a {}
// // arm64 { minSdkVersion 21 }
// // x86 {}
// }
修改依赖关系:
代码语言:javascript复制dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:preference-v7:23.0.1'
compile 'com.android.support:support-annotations:23.0.1'
compile 'com.squareup:otto:1.3.8'
compile project(':ijkplayer-java')
// compile project(':ijkplayer-exo')
// all32Compile project(':ijkplayer-armv5')
compile project(':ijkplayer-armv7a')
// all32Compile project(':ijkplayer-x86')
// all64Compile project(':ijkplayer-armv5')
// all64Compile project(':ijkplayer-armv7a')
// all64Compile project(':ijkplayer-arm64')
// all64Compile project(':ijkplayer-x86')
// all64Compile project(':ijkplayer-x86_64')
// compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
// compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'
// all32Compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
// all32Compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
// all32Compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
// all64Compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
// all64Compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
// all64Compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
// all64Compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
// all64Compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8'
// armv5Compile project(':player-armv5')
// armv7aCompile project(':player-armv7a')
// arm64Compile project(':player-arm64')
// x86Compile project(':player-x86')
// x86_64Compile project(':player-x86_64')
}
5、 配置好你的NDK环境
点击Android Studio的菜单栏File > Project Structure > SDK Location
选择你的NDK路径,笔者这里使用的是NDKr16。
一般NDK的版本有差异,不建议使用最新的NDK版本。
至此修改就完成了,点击Android Studio的Sync Project with Gradle Files
图标按钮等待编译完成即可愉快地运行ijkplayer-example
项目啦,
同时也可以愉快地使用AS查看ijkpalyer的源代码啦。