編譯Android Ijkplayer以及問題

編譯Android Ijkplayer以及問題

一、Linux 環(huán)境安裝的程序

下載:

  1. git

    yum install git
    
  2. yasm

    yum install yasm
    
  3. ndk

    下載ndk 滑蚯,推薦ndk 14 以上的

配置環(huán)境變量

配置ndk矛纹、sdk (交叉編譯時需要查找頭文件和庫文件),打開/etc/profile 文件

vim /etc/profile

在文件末尾加上
export ANDROID_SDK=你的SDF安裝路徑
export ANDROID_NDK=/root/ndk/android-ndk-r14b  

NDK 的安裝路徑霜医,使用14版本以上的會出問題齿拂,問題分析在后面,雖然能改支子,但是不太清楚內(nèi)部有什么限制创肥,所有還是老實的用14版本的

保存,然后執(zhí)行 source /etc/profile 刷新環(huán)境變量

二、下載ijkplayer

git官網(wǎng)上的Build Android

git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android
cd ijkplayer-android
git checkout -B latest k0.8.8

./init-android.sh

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

cd ..
./compile-ijk.sh all

github 下載慢叹侄,可以在碼云上搜ijkplayer巩搏,然后下載下來,這里提供一個地址

git clone https://gitee.com/mirrors/ijkplayer.git ijkplayer-android

切換到最新分支:

git checkout -B latest k0.8.8

先不要執(zhí)行 ./init-android.sh趾代,如果你播放器需要支持rtp贯底、tcp、rtsp等(具體自行谷歌)撒强,需要修改配置文件禽捆,如果不需要修改,跳過下面的步驟1

1飘哨、 config 目錄性有四個文件

image-20200911113704739

三個module-...開頭的文件就是配置文件胚想,其實里面就是定義一些變量(如下圖),用于開啟或關(guān)閉支持庫芽隆,默認使用的module-default.sh浊服,如果能看懂就可以自行開啟或者關(guān)閉,看不懂就老實用module-default.sh

<img src=https://img-blog.csdnimg.cn/202009111614390.png?/>

其中module.sh 文件可以理解為指向其他文件的文件胚吁,編譯時牙躺,腳本文件不清楚你使用三個配置文件的哪個文件,所以使用linux 命令

ln -s module-default.sh module.sh

來指定module.sh 鏈接到module-default.sh文件腕扶,當(dāng)然也可以

ln -s module-lite-hevc.sh module.sh
ln -s module-lite.sh module.sh
來鏈接到其他文件孽拷,反正腳本文件執(zhí)行時執(zhí)行的是module.sh腳本文件

2、 如果直接執(zhí)行 init-android.sh 文件半抱,會從github 上拉取 armv5 脓恕、armv7、arm64代虾、x86进肯、x86_64 架構(gòu)的源碼,這里我只需要armv7a 的棉磨,所有其他的都關(guān)了江掩,如果需要可以自行打開

#IJK_FFMPEG_UPSTREAM=https://github.com/Bilibili/FFmpeg.git
#IJK_FFMPEG_FORK=https://github.com/Bilibili/FFmpeg.git

IJK_FFMPEG_UPSTREAM=https://gitee.com/yuazhen/FFmpeg.git
IJK_FFMPEG_FORK=https://gitee.com/yuazhen/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

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"

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

因為拉取代碼也是在github 上獲取的,這里修改了下載源碼路徑

#IJK_FFMPEG_UPSTREAM=https://github.com/Bilibili/FFmpeg.git
#IJK_FFMPEG_FORK=https://github.com/Bilibili/FFmpeg.git

IJK_FFMPEG_UPSTREAM=https://gitee.com/yuazhen/FFmpeg.git
IJK_FFMPEG_FORK=https://gitee.com/yuazhen/FFmpeg.git

init-android.sh 里面也會去下載libyuv soundtouch庫的代碼乘瓤,這兩個庫不大环形,所以可以不用修改下載地址,執(zhí)行 init-android.sh 文件

./init-android.sh

完成后進入到 android/contrib 目錄

cd android/contrib

接下來開始編譯下載的ffmpeg 庫衙傀,首先先清理

./compile-ffmpeg.sh clean

因為只下載了armv7a 抬吟,編譯ffmpeg 不能編譯全部,這里只編譯 armv7a的(如果是多架構(gòu)編譯看后文)

./compile-ffmpeg.sh armv7a

(這里可能會因為ndk 版本問題編譯出錯统抬,具體修改看后面問題)

執(zhí)行完之后 就會在 ../ijkplayer-android/android/contrib/build/ffmpeg-armv7a/output 目錄下生成ffmpeg 的頭文件和庫文件

image-20200911140429954

以上的都是編譯ijkplayer 所需要的東西火本,接下來才是真正編譯ijkplayer

這里只下載了armv7a危队,所有只編譯armv7a的

返回上一層目錄

cd ..
./compile-ijk.sh armv7a

成功后會在/ijkplayer/ijkplayer-android/android/ijkplayer 目錄下對應(yīng)的cpu 架構(gòu)生成ijkplayer的動態(tài)庫文件,so 文件是放在對應(yīng)架構(gòu)的 ../src/main/libs/armeabi-v7a

image-20200911141237983
image-20200911141313915

ijkplayer-example 就是示例項目代碼

三钙畔、編譯遇到的問題

1茫陆、You need the NDKr10e or later

在執(zhí)行 ./compile-ffmpeg.sh armv7a 的時候

如果ndk版本大于 14,會報:

image-20200911141645858

以下是分析原因擎析,如果看結(jié)果直接略過

打開 comfile-ffmpeg.sh 文件簿盅,省略部分,主要內(nèi)容:

case "$FF_TARGET" in
    "")
        echo_archs armv7a
        sh tools/do-compile-ffmpeg.sh armv7a
    ;;
    #這里這里
    armv5|armv7a|arm64|x86|x86_64)
        echo_archs $FF_TARGET $FF_TARGET_EXTRA
        sh tools/do-compile-ffmpeg.sh $FF_TARGET $FF_TARGET_EXTRA
        echo_nextstep_help
    ;;
    .
    .
    .
    .
    *)
        echo_usage
        exit 1
    ;;
esac

就是感覺傳入進來的armv7a 字符匹配 揍魂,然后執(zhí)行

sh tools/do-compile-ffmpeg.sh $FF_TARGET $FF_TARGET_EXTRA

FF_TARGET 這里是傳進來的armv7a 
FF_TARGET_EXTRA 這里沒傳進來桨醋,為空

就是執(zhí)行
sh tools/do-compile-ffmpeg.sh armv7a

又去執(zhí)行當(dāng)前目錄下tools包下的do-compile-ffmpeg.sh 文件,帶個armv7a 參數(shù)進去现斋;(真正的編譯腳本不是comfile-ffmpeg.sh 而是do-compile-ffmpeg.sh 喜最,所有單個文件也可以直接執(zhí)行./tools/do-compile-ffmpeg.sh armv7a ,執(zhí)行的目錄還是在compile-ffmpeg.sh文件所在的目錄)

image-20200911142324453

do-compile-ffmpeg.sh 內(nèi)容的開頭():

FF_ARCH=$1
FF_BUILD_OPT=$2
echo "FF_ARCH=$FF_ARCH"
echo "FF_BUILD_OPT=$FF_BUILD_OPT"
if [ -z "$FF_ARCH" ]; then
    echo "You must specific an architecture 'arm, armv7a, x86, ...'."
    echo ""
    exit 1
fi
.
.
設(shè)置各種變量
.
.

#--------------------
echo ""
echo "--------------------"
echo "[*] make NDK standalone toolchain"
echo "--------------------"
. ./tools/do-detect-env.sh
.
.
.

判斷 FF_ARCH 參數(shù)是否空步责,如果為空就輸出 "You must specific an architecture 'arm, armv7a, x86, ...'. 然后退出返顺,

這里的 FF_ARCH 就是傳進來的armv7a(這里講廢話了),有條命令. ./tools/do-detect-env.sh蔓肯;

上面都是廢話,可以不用看振乏,細節(jié)而已蔗包,下面才是重要內(nèi)容

在編譯腳本之前會執(zhí)行do-detect-env.sh 文件檢查運行環(huán)境和NDK 版本

#! /usr/bin/env bash

set -e

UNAME_S=$(uname -s)
UNAME_SM=$(uname -sm)
echo "build on $UNAME_SM"

echo "ANDROID_NDK=$ANDROID_NDK"

if [ -z "$ANDROID_NDK" ]; then
    echo "You must define ANDROID_NDK before starting."
    echo "They must point to your NDK directories."
    echo ""
    exit 1
fi



# try to detect NDK version
export IJK_GCC_VER=4.9
export IJK_GCC_64_VER=4.9
export IJK_MAKE_TOOLCHAIN_FLAGS=
export IJK_MAKE_FLAG=
export IJK_NDK_REL=$(grep -o '^r[0-9]*.*' $ANDROID_NDK/RELEASE.TXT 2>/dev/null | sed 's/[[:space:]]*//g' | cut -b2-)
case "$IJK_NDK_REL" in
    10e*)
        # we don't use 4.4.3 because it doesn't handle threads correctly.
        if test -d ${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.8
        # if gcc 4.8 is present, it's there for all the archs (x86, mips, arm)
        then
            echo "NDKr$IJK_NDK_REL detected"

            case "$UNAME_S" in
                Darwin)
                    export IJK_MAKE_TOOLCHAIN_FLAGS="$IJK_MAKE_TOOLCHAIN_FLAGS --system=darwin-x86_64"
                ;;
                CYGWIN_NT-*)
                    export IJK_MAKE_TOOLCHAIN_FLAGS="$IJK_MAKE_TOOLCHAIN_FLAGS --system=windows-x86_64"
                ;;
            esac
        else
            echo "You need the NDKr10e or later"
            exit 1
        fi
    ;;
    *)
        IJK_NDK_REL=$(grep -o '^Pkg\.Revision.*=[0-9]*.*' $ANDROID_NDK/source.properties 2>/dev/null | sed 's/[[:space:]]*//g' | cut -d "=" -f 2)
        echo "IJK_NDK_REL=$IJK_NDK_REL"
         #這里這里這里
        case "$IJK_NDK_REL" in
            11*|12*|13*|14*)
                if test -d ${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.9
                then
                    echo "NDKr$IJK_NDK_REL detected"
                else
                    echo "You need the NDKr10e or later"
                    exit 1
                fi
            ;;
            *)
                echo "You need the NDKr10e or later"
                exit 1
            ;;
        esac
    ;;
esac


case "$UNAME_S" in
    Darwin)
        export IJK_MAKE_FLAG=-j`sysctl -n machdep.cpu.thread_count`
    ;;
    CYGWIN_NT-*)
        IJK_WIN_TEMP="$(cygpath -am /tmp)"
        export TEMPDIR=$IJK_WIN_TEMP/

        echo "Cygwin temp prefix=$IJK_WIN_TEMP/"
    ;;
esac

export IJK_NDK_REL=$(grep -o '^r[0-9]*.*' $ANDROID_NDK/RELEASE.TXT 2>/dev/null | sed 's/[[:space:]]*//g' | cut -b2-)

使用正則判斷NDK的版本

如果NDK 版本是10e的,執(zhí)行下面的

case "$IJK_NDK_REL" in
    10e*)

如果是其他的慧邮,執(zhí)行

 case "$IJK_NDK_REL" in
            11*|12*|13*|14*) # 這里就是判斷NDK 版本是不是11调限、12、13误澳、14
     if test -d ${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.9  #檢查對應(yīng)版本的是否存在
     這里只檢查了 11*|12*|13*|14*四個版本的耻矮,不妨加上 17試試
     
      11*|12*|13*|14*|17*)

保存之后執(zhí)行 ./compile-ffmpeg.sh armv7a ,接著又報:

image-20200911150506225

因為編譯ffmpeg 使用的Android平臺默認為 9,arm 平臺最低為14忆谓,所以在do-comfile-ffmpeg.sh 文件中加入

FF_ANDROID_PLATFORM=android-24 #我這里的sdk 版本為24
.
.
.
#----- armv7a begin -----
if [ "$FF_ARCH" = "armv7a" ]; then
    #這里這里
    FF_ANDROID_PLATFORM=android-24

    FF_BUILD_NAME=ffmpeg-armv7a
    FF_BUILD_NAME_OPENSSL=openssl-armv7a
    FF_BUILD_NAME_LIBSOXR=libsoxr-armv7a
    FF_SOURCE=$FF_BUILD_ROOT/$FF_BUILD_NAME

    FF_CROSS_PREFIX=arm-linux-androideabi
    FF_TOOLCHAIN_NAME=${FF_CROSS_PREFIX}-${FF_GCC_VER}

    FF_CFG_FLAGS="$FF_CFG_FLAGS --arch=arm --cpu=cortex-a8"
    FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-neon"
    FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-thumb"

    FF_EXTRA_CFLAGS="$FF_EXTRA_CFLAGS -march=armv7-a -mcpu=cortex-a8 -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb"
    FF_EXTRA_LDFLAGS="$FF_EXTRA_LDFLAGS -Wl,--fix-cortex-a8"

    FF_ASSEMBLER_SUB_DIRS="arm"
 elif [ "$FF_ARCH" = "armv5" ]; then
.
.
.

保存之后執(zhí)行 ./compile-ffmpeg.sh armv7a

2裆装、ERROR: Failed to create toolchain

在執(zhí)行./compile-ffmpeg.sh armv7a 的時候有些系統(tǒng)會保存 Failed to create toolchain

這是因為linux 系統(tǒng)有些使用python版本 是python3(python2的我沒試過)

可以使用rpm 命令檢查python 版本

rpm -qa | grep python
image-20200911151733008

在執(zhí)行do-compile-ffmpeg.sh 中會執(zhí)行 NDK的 $ANDROID_NDK/build/tools/make-standalone-toolchain.sh文件

make-standalone-toolchain.sh 文件最后會運行python 腳本 make_standalone_toolchain.py

PLATFORM_NUMBER=${PLATFORM#android-}
if [ -n "$PLATFORM_NUMBER" ]; then
  PLATFORM_ARG="--api $PLATFORM_NUMBER"
else
  PLATFORM_ARG=""
fi
#修改前的
#run python `dirname $0`/make_standalone_toolchain.py \
#    --arch $ARCH $PLATFORM_ARG --stl $STL $INSTALL_ARG $FORCE_ARG
    
#修改后的
python3 `dirname $0`/make_standalone_toolchain.py \
    --arch $ARCH $PLATFORM_ARG --stl $STL $INSTALL_ARG $FORCE_ARG
    
fail_panic "Failed to create toolchain."

if [ -n "$INSTALL_DIR" ]; then
    dump "Toolchain installed to $INSTALL_DIR."
else
    dump "Package installed to $PACKAGE_DIR."
fi

如果是python3 版本就會報錯,因為run python 命令運行不了python3的文件(.py)倡缠,所以把run python改成

python3(python2沒試過)

3哨免、./compile-ijk.sh armv7a 報錯

image-20200911153625596

在最后關(guān)鍵時刻,使用NDK 14b編譯 ijkplayer 竟然不行昙沦,就感覺還沒拉出來完琢唾,中間夾斷了那么難受,最后是把NDK 版本改成 17的才可以

四盾饮、編譯多架構(gòu)

比如這里需要編譯 armv7a 與arm64

首先init-android.sh 必須下載對應(yīng)架構(gòu)的源碼

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"
//下載armv7a 與arm64
pull_fork "armv7a"
pull_fork "arm64"
#pull_fork "x86"
#pull_fork "x86_64"

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

接著修改compile-ffmpeg.sh 文件采桃,F(xiàn)F_ACT_ARCHS_64 只保留armv7a 懒熙、arm64

.
.
.
#FF_ACT_ARCHS_32="armv5 armv7a x86"
#FF_ACT_ARCHS_64="armv5 armv7a arm64 x86 x86_64"

#這里是32位于64位,現(xiàn)在一般的都是64位
FF_ACT_ARCHS_32="armv7a"
FF_ACT_ARCHS_64="armv7a arm64"
FF_ACT_ARCHS_ALL=$FF_ACT_ARCHS_64
.
.
.

執(zhí)行腳本時候使用的就是

./compile-ffmpeg.sh all

同樣普办,接著修改compile-ijk.sh 文件 ACT_ABI_64 只保留armv7a 煌珊、arm64

.
.
.
REQUEST_TARGET=$1
REQUEST_SUB_CMD=$2
#ACT_ABI_32="armv5 armv7a x86"
#ACT_ABI_64="armv5 armv7a arm64 x86 x86_64"

ACT_ABI_32="armv7a"
ACT_ABI_64="armv7a arm64"
ACT_ABI_ALL=$ACT_ABI_64
UNAME_S=$(uname -s)
.
.
.

執(zhí)行腳本時候使用的就是

./compile-ijk.sh all
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市泌豆,隨后出現(xiàn)的幾起案子定庵,更是在濱河造成了極大的恐慌,老刑警劉巖踪危,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔬浙,死亡現(xiàn)場離奇詭異,居然都是意外死亡贞远,警方通過查閱死者的電腦和手機畴博,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蓝仲,“玉大人俱病,你說我怎么就攤上這事「そ幔” “怎么了亮隙?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長垢夹。 經(jīng)常有香客問我溢吻,道長,這世上最難降的妖魔是什么果元? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任促王,我火速辦了婚禮,結(jié)果婚禮上而晒,老公的妹妹穿的比我還像新娘蝇狼。我一直安慰自己,他們只是感情好倡怎,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布迅耘。 她就那樣靜靜地躺著,像睡著了一般诈胜。 火紅的嫁衣襯著肌膚如雪豹障。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天焦匈,我揣著相機與錄音血公,去河邊找鬼。 笑死缓熟,一個胖子當(dāng)著我的面吹牛累魔,可吹牛的內(nèi)容都是我干的摔笤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼垦写,長吁一口氣:“原來是場噩夢啊……” “哼吕世!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起梯投,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤命辖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后分蓖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尔艇,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年么鹤,在試婚紗的時候發(fā)現(xiàn)自己被綠了终娃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蒸甜,死狀恐怖棠耕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情柠新,我是刑警寧澤窍荧,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站登颓,受9級特大地震影響搅荞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜框咙,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望痢甘。 院中可真熱鬧喇嘱,春花似錦、人聲如沸塞栅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽放椰。三九已至作烟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間砾医,已是汗流浹背拿撩。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留如蚜,地道東北人压恒。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓影暴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親探赫。 傳聞我的和親對象是個殘疾皇子型宙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354