前言
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的源碼目錄下面運作一下這句指令:
sh android/patch-debugging-with-lldb.sh armv7a
運作這條指令之後我們發現報錯了:
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檔案就是:
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 <[email protected]>
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庫檔案夾位置:
android {
//删除以下内容
//sourceSets.main {
// jniLibs.srcDirs 'src/main/libs'
// jni.srcDirs = [] // This prevents the auto generation of Android.mk
//}
}
添加native代碼主編譯腳本Android.mk的檔案路徑:
android {
//添加以下内容
externalNativeBuild {
ndkBuild {
path "src/main/jni/Android.mk"
}
}
}
設定編譯腳本的參數:
android {
defaultConfig {
//添加以下内容
externalNativeBuild {
ndkBuild {
arguments "NDK_APPLICATION:=src/main/jni/Application.mk"
abiFilters "armeabi-v7a"
}
}
}
}
開啟工程的debug模式:
android {
buildTypes {
//添加以下内容
debug {
debuggable true
jniDebuggable true
ndk {
debuggable true
}
}
}
}
4、 修改
ijkplayer-example
的
build.gradle
修改檔案:
ijkplayer/ijkplayer-example/build.gradle
:
删除管道配置:
// 注釋掉這個,因為在某些gradle版本上會報Flavors緯度不一緻的錯誤
// productFlavors {
// all32 { minSdkVersion 9 }
// all64 { minSdkVersion 21 }
// // armv5 {}
// // armv7a {}
// // arm64 { minSdkVersion 21 }
// // x86 {}
// }
修改依賴關系:
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的源代碼啦。
對于音視訊開發感興趣的童鞋請掃碼關注公衆号共同學習進步
掃碼關注公衆号【音視訊開發進階】,一起學習多媒體音視訊開發~~~