mac系统 ijk(Android)编译

2019-12-13  本文已影响0人  DON_1007
ijk github地址:ijk github

按照github文档说的,如果不想自己编译ijk库,Android可通过gradle依赖现有的库

# required
allprojects {
    repositories {
        jcenter()
    }
}

dependencies {
    # required, enough for most devices.
    compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
    compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'

    # Other ABIs: optional
    compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
    compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
    compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
    compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8'

    # ExoPlayer as IMediaPlayer: optional, experimental
    compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'
}

这种依赖方式gradle3.0之前的版本的依赖方式,gardle3.0之后的版本,按需请将compile换成implementationapi

如果自己编译ijk库需要参照下面的流程

1、安装 homebrew, git, yasm

先安装homebrew,打开homebrew官网,可以看到安装方法

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

然后通过homebrew安装gityasm

brew install git
brew install yasm

接下来需要安装配置Android的编译环境,分别下载安装
JDKAndroid StudioAndroid SDKAndroid NDK,并在~/.bash_profile中完成环境变量设置。安装配置Android的编译环境的时候需要注意以下两点:

...
export ANDROID_SDK=/Users/lb/Library/Android/sdk
export ANDROID_NDK=/Users/lb/developer/android-ndk-r10b
...

声明 ANDROID_SDKANDROID_NDK变量,是因为ijk的编译脚本中是按照这两个变量名去系统中查找SDKNDK的。

2、下载编译Android ijk

下载源码

git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android

表示新建文件夹ijkplayer-android,并下载ijkplayer源码到该文件夹

cd ijkplayer-android

进入文件夹ijkplayer-android,可以看到这里面不只有Android源码,还有iOS源码,整个项目文件结构如下:

ijkplayer-android/
├── COPYING.GPLv2
 ...
├── README.md
├── android
│   ├── android-ndk-prof -> ../../../../../../ijkprof/android-ndk-profiler-dummy/jni
│   ├── build-on-travis.sh
│   ├── compile-ijk.sh
│   ├── contrib
│   │   ├── compile-ffmpeg.sh
│   │   ├── compile-libsoxr.sh
│   │   ├── compile-openssl.sh
│   │   ├── setup-as-commiter.sh
│   │   ├── sync-mirrors.sh
│   │   └── tools
│   │       ├── do-compile-ffmpeg.sh
│   │       ├── do-compile-libsoxr.sh
│   │       ├── do-compile-openssl.sh
│   │       └── do-detect-env.sh
│   ├── ijk-addr2line.sh
│   ├── ijk-ndk-stack.sh
│   ├── ijkplayer
│   │   ├── build.gradle
│   │   ├── gradle
...
│   │   ├── gradle.properties
│   │   ├── gradlew
│   │   ├── gradlew.bat
│   │   ├── ijkplayer-arm64
│   │   │   ├── build.gradle
│   │   │   ├── gradle.properties
│   │   │   ├── proguard-rules.pro
│   │   │   └── src
│   │   │       ├── androidTest
...
│   │   │       └── main
...
│   │   ├── ijkplayer-example
│   │   │   ├── build.gradle
│   │   │   ├── proguard-rules.pro
│   │   │   └── src
│   │   │       ├── androidTest
....
│   │   │       └── main
│   │   │           ├── AndroidManifest.xml
│   │   │           ├── java
│   │   │           │   └── tv
│   │   │           │       └── danmaku
│   │   │           │           └── ijk
│   │   │           │               └── media
│   │   │           │                   └── example
│   │   │           │                       ├── activities
│   │   │           │                       │   ├── FileExplorerActivity.java
...
│   │   ├── ijkplayer-exo
...
├── compile-android-j4a.sh
├── config
│   ├── module-default.sh
│   ├── module-lite-hevc.sh
│   ├── module-lite.sh
│   └── module.sh -> module-lite.sh
├── doc
│   └── preflight_checklist.md
├── extra
│   └── init-extra.sh
├── ijkmedia
│   ├── Android.mk
│   ├── ijkj4a
│   │   ├── Android.mk
│   │   ├── Makefile
│   │   ├── j4a
│   │   │   ├── class
│   │   │   │   ├── android
│   │   │   │   │   ├── media
│   │   │   │   │   │   ├── AudioTrack.c
│   │   │   │   │   │   ├── AudioTrack.h
...
│   │   │   │   │   └── os
│   │   │   │   │       ├── Build.c
│   │   │   │   │       ├── Build.h
│   │   │   │   │       ├── Build.include.j4a
│   │   │   │   │       ├── Build.loader.j4a
│   │   │   │   │       ├── Bundle.c
│   │   │   │   │       ├── Bundle.h
│   │   │   │   │       ├── Bundle.include.j4a
│   │   │   │   │       └── Bundle.loader.j4a
│   │   │   │   ├── java
│   │   │   │   │   ├── nio
│   │   │   │   │   │   ├── Buffer.c
│   │   │   │   │   │   ├── Buffer.h
│   │   │   │   │   │   ├── Buffer.include.j4a
│   │   │   │   │   │   ├── Buffer.loader.j4a
...
│   │   │   │   └── tv
...
│   ├── ijkplayer
│   │   ├── Android.mk
│   │   ├── android
│   │   │   ├── ffmpeg_api_jni.c
│   │   │   ├── ffmpeg_api_jni.h
...
│   │   └── version.sh
│   └── ijksdl
│       ├── Android.mk
│       ├── android
│       │   ├── android_audiotrack.c
│       │   ├── android_audiotrack.h
│       │   ├── android_nativewindow.c
│       │   ├── android_nativewindow.h
...
├── ijkprof
│   └── android-ndk-profiler-dummy
│       └── jni
│           ├── Android-include.mk
│           ├── Android.mk
│           ├── prof.c
│           └── prof.h
...
├── init-android-exo.sh
├── init-android-j4a.sh
├── init-android-libsoxr.sh
├── init-android-libyuv.sh
├── init-android-openssl.sh
├── init-android-prof.sh
├── init-android-soundtouch.sh
├── init-android.sh
├── init-config.sh
├── init-ios-openssl.sh
├── init-ios.sh
├── ios
│   ├── IJKMediaDemo
...
│   ├── IJKMediaPlayer
│   │   ├── IJKMediaFramework
│   │   │   ├── IJKMediaFramework.h
│   │   │   └── Info.plist
...
│   │   │   └── ijkmedia
│   │   │       ├── ijkplayer
│   │   │       │   └── ios
...
│   │   │       └── ijksdl
│   │   │           └── ios
...
│   ├── IJKMediaPodDemo
│   │   ├── IJKMediaPodDemo
...
└── version.sh

可以看到整个目录大致分为源码demo脚本这几个部分
新建本地分支latest并同步tag k0.8.8的源码

git checkout -B latest k0.8.8

执行脚本init-android.sh

./init-android.sh

看下init-android.sh这个脚本都干了啥?

IJK_FFMPEG_UPSTREAM=https://github.com/Bilibili/FFmpeg.git
IJK_FFMPEG_FORK=https://github.com/Bilibili/FFmpeg.git
IJK_FFMPEG_COMMIT=ff3.4--ijk0.8.7--20180103--001
IJK_FFMPEG_LOCAL_REPO=extra/ffmpeg

set -e
TOOLS=tools

git --version

echo "== pull ffmpeg base =="
sh $TOOLS/pull-repo-base.sh $IJK_FFMPEG_UPSTREAM $IJK_FFMPEG_LOCAL_REPO

通过脚本内容可以看到,init_android.sh脚本会先调用tools目录下的脚本pull-repo-base.sh下载FFmpeg源码到extra/ffmpeg目录下,然后同步对应平台的源码到android/contrib/ffmpeg-x目录下

function pull_fork()
{
    echo "== pull ffmpeg fork $1 =="
    sh $TOOLS/pull-repo-ref.sh $IJK_FFMPEG_FORK android/contrib/ffmpeg-$1 ${IJK_FFMPEG_LOCAL_REPO}
    cd android/contrib/ffmpeg-$1
    git checkout ${IJK_FFMPEG_COMMIT} -B ijkplayer
    cd -
}

pull_fork "armv5"
pull_fork "armv7a"
pull_fork "arm64"
pull_fork "x86"
pull_fork "x86_64"

脚本执行完之后,可以看到在extra/目录下多了个ffmpeg文件夹,在 android/contrib/目录下,多了ffmpeg-armv5等文件夹
init_android.sh脚本的最后会调用下面三个脚本

./init-config.sh
./init-android-libyuv.sh
./init-android-soundtouch.sh

3、编译ffmpeg

cd android/contrib
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all

compile-ffmpeg.sh 根据传入参数all,会调用tools/do-compile-ffmpeg.sh

   all|all64)
        echo_archs $FF_ACT_ARCHS_64
        for ARCH in $FF_ACT_ARCHS_64
        do
            sh tools/do-compile-ffmpeg.sh $ARCH $FF_TARGET_EXTRA
        done
        echo_nextstep_help
    ;;

执行完成之后会在android/contrib/build/ffmpeg-x/output/文件夹下生成libijkffmpeg.so等文件,例如用于armv7a平台的so库就会在android/contrib/build/ffmpeg-armv7a/output/目录下生成。

4、编译ijk

cd ..
./compile-ijk.sh all

compile-ijk.sh根据传入参数调用方法do_ndk_build编译

    all|all64)
        for ABI in $ACT_ABI_64
        do
            do_ndk_build "$ABI" $REQUEST_SUB_CMD;
        done
    ;;

do_ndk_build进入目标编译平台代码所在的目录,调用do_sub_cmd并传入参数

do_ndk_build () {
    PARAM_TARGET=$1
    PARAM_SUB_CMD=$2
    case "$PARAM_TARGET" in
        armv5|armv7a)
            cd "ijkplayer/ijkplayer-$PARAM_TARGET/src/main/jni"
            do_sub_cmd $PARAM_SUB_CMD
            cd -
        ;;
        arm64|x86|x86_64)
            cd "ijkplayer/ijkplayer-$PARAM_TARGET/src/main/jni"
            if [ "$PARAM_SUB_CMD" = 'prof' ]; then PARAM_SUB_CMD=''; fi
            do_sub_cmd $PARAM_SUB_CMD
            cd -
        ;;
    esac
}

do_sub_cmd调用NDK编译

do_sub_cmd () {
    SUB_CMD=$1
    if [ -L "./android-ndk-prof" ]; then
        rm android-ndk-prof
    fi

    if [ "$PARAM_SUB_CMD" = 'prof' ]; then
        echo 'profiler build: YES';
        ln -s ../../../../../../ijkprof/android-ndk-profiler/jni android-ndk-prof
    else
        echo 'profiler build: NO';
        ln -s ../../../../../../ijkprof/android-ndk-profiler-dummy/jni android-ndk-prof
    fi

    case $SUB_CMD in
        prof)
            $ANDROID_NDK/ndk-build $FF_MAKEFLAGS
        ;;
        clean)
            $ANDROID_NDK/ndk-build clean
        ;;
        rebuild)
            $ANDROID_NDK/ndk-build clean
            $ANDROID_NDK/ndk-build $FF_MAKEFLAGS
        ;;
        *)
            $ANDROID_NDK/ndk-build $FF_MAKEFLAGS
        ;;
    esac
}

编译完整之后可以在对应的平台目录下生成libijkplayer.solibijksdl.so,例如用于armv7a平台的so就会在android/ijkplayer/ijkplayer-armv7a/src/main/obj/local/armeabi-v7a目录下生成。

PS:前面配置环境变量的时候,在~/.bash_profile中配置的变量$ANDROID_NDK就是用在这里的。

5、Android Studio导入android/ijkplayer/

导入之后可以看到按照芯片架构分成了很多module

ijkplayer.png

运行主module ijkplayer-example
选择sd卡中的视频播放,效果如下

总结:ijk player源码的编译步骤如下

#1、下载源码
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android
cd ijkplayer-android
git checkout -B latest k0.8.8
./init-android.sh

#2、编译ffmpeg
cd android/contrib
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all

#3、编译ijk
cd ..
./compile-ijk.sh all

然后Android Studio导入android/ijkplayer/,选择module ijkplayer-example运行,就可以得到一个ijk playerdemo播放器程序。

上一篇下一篇

猜你喜欢

热点阅读