天天看點

如何将ijkplayer引入AS工程中進行二次開發

前言

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的源代碼啦。

對于音視訊開發感興趣的童鞋請掃碼關注公衆号共同學習進步

如何将ijkplayer引入AS工程中進行二次開發

掃碼關注公衆号【音視訊開發進階】,一起學習多媒體音視訊開發~~~