如何将ijkplayer引入AS工程中进行二次开发

2020-04-30 15:57:53 浏览数 (1)

前言

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这个文件:

代码语言:javascript复制
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:

代码语言:javascript复制
//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-examplebuild.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的源代码啦。

0 人点赞