帶你走進腳本世界,ijkplayer之【init-ios.sh】腳本分析

前言

集成ijkplayer,需要執行腳本init-ios.sh,那么init-ios.sh腳本干嘛用的了,花了半天時間,學習了下shell腳本,感覺腳本語言學起來還是比較容易上手的,現在僅僅能看懂了,但是要自己寫,還需要花點時間,下面就拿腳本文件練練手,不知道理解的對不對,還希望多交流.
后續會持續發布,教你從零開始搭建一個完整的iOS直播app,希望能幫助到更多的人更快的了解直播。
如果喜歡我的文章,可以關注我微博:袁崢Seemygo

ijkplayer集成官方說明

執行腳本.png

下載ijkplayer,查看init-ios.sh文件

  • 去到B站得github主頁,找到ijkplayer項目,下載源碼 ijkplayer下載地址
  • init-ios.sh目錄
Snip20160827_4.png

一、了解shell基本語法

#  ***********shell基本語法***********
#   1. # : 注釋

#   2. 定義變量 a = 3

#   3. $a : 獲取變量a => $a = 3

#   4. 條件語句 if 條件 then 執行語句 fi,滿足條件 就會than后面的執行語句

#   5. set -e 任何語句的執行結果不是true則應該退出。這樣的好處是防止錯誤像滾雪球般變大導致一個致命的錯誤,而這些錯誤本應該在之前就被處理掉

#   6. 函數定義 function 函數名()

#   7. echo 打印

#   8. sh: 執行腳本文件 sh a.sh =》 執行腳本文件a.sh

#   9. $1:獲取參數第一個參數

#   10.$*:獲取參數所有參數

#   11.case:邏輯分支語句
   
   case 值 in
        條件1)command1 ;;
        *)command2 ;;
   esac
   
   值等于條件1,就會執行command1,否則不執行,不滿足,就會執行command2
   
   * : 表示當使用前面的各種模式均無法匹配該變量時,將執行*后的命令

#   12.for:循環語句

    for var in item1 item2 ... itemN
    do
    command1
    done
    
    遍歷in后邊的變量,一個一個給var賦值,在執行command1

#   13.cd - : 回到上一級目錄
#   14.腳本開頭 #!/usr/bin/env作用 : 在linux的一些bash的腳本,需在開頭一行指定腳本的解釋程序,如: #!/usr/bin/env
#   15.-z 字符串 : 沒有字符串就為真
#   16.-o : 或
#   17.!  : 非
#   18.-d : 是目錄就為真

二、分析【init-ios.sh】腳本做的事情

  • init-ios.sh腳本作用 :腳本會自動下載ffmpeg的主干代碼
    • 1.找到tools目錄的pull-repo-base.sh腳本并執行,這個腳本用于下載站托管的github上的FFmpeg分支源碼和FFmpeg依賴包。
    • 2.找到tools目錄的pull-repo-ref.sh腳本并執行,這個腳本用于獲取B站托管的github上的FFmpeg分支,根據不同的目標平臺放置不同工作目錄
    • 后續會詳細介紹pull-repo-base.sh和pull-repo-ref.sh腳本
Snip20160827_5.png

1、首先定義了5個變量,用于下載ffmpeg源碼和ffmpeg依賴包和創建目錄的文件

// B站托管與github的ffmpeg分支的下載地址
IJK_FFMPEG_UPSTREAM=https://github.com/Bilibili/FFmpeg.git

// IJK_FFMPEG_FORK,和IJK_FFMPEG_UPSTREAM一樣
IJK_FFMPEG_FORK=https://github.com/Bilibili/FFmpeg.git

// ffmpeg版本
IJK_FFMPEG_COMMIT=ff3.1--ijk0.6.1--20160824--001

// ffmpeg下載目錄
IJK_FFMPEG_LOCAL_REPO=extra/ffmpeg

// gas-preprocessor的下載地址
// gas-preprocessor是用于編譯FFmpeg的perl預處理腳本
IJK_GASP_UPSTREAM=https://github.com/Bilibili/gas-preprocessor.git

2、定義了6個變量,用于描述不同架構下的源碼存放目錄

// 定義文件目錄
TOOLS=tools

// iOS6架構
FF_ALL_ARCHS_IOS6_SDK="armv7 armv7s i386"

// iOS7架構
FF_ALL_ARCHS_IOS7_SDK="armv7 armv7s arm64 i386 x86_64"

// iOS8架構
FF_ALL_ARCHS_IOS8_SDK="armv7 arm64 i386 x86_64"

// 所有架構 = iOS8架構
FF_ALL_ARCHS=$FF_ALL_ARCHS_IOS8_SDK

// 獲取腳本第一個參數
FF_TARGET=$1

3、控制腳本執行

# 每個腳本都應該在文件開頭加上set -e
# 用來控制腳本執行,只要有一行語句的執行出錯就會退出。
set -e

4、定義4個函數,用來執行腳本,下載ffmpeg源碼和ffmpeg依賴庫,并且放置到對應平臺架構的目錄下

  • 4.1 echo_ffmpeg_version函數功能::打印IJK_FFMPEG_COMMIT這個變量值
# 定義函數【echo_ffmpeg_version】

function echo_ffmpeg_version() {
#   輸出 ffmpeg版本號
    echo $IJK_FFMPEG_COMMIT
}
  • 4.2 pull_common函數功能
    • 1.查看git版本
    • 2.執行pull-repo-base.sh腳本 下載gas-preprocessor
    • 3.執行pull-repo-base.sh腳本 下載ffmpeg
#  定義函數【pull_common】
function pull_common() {
#  查看git版本
    git --version

#   輸出 "== pull gas-preprocessor base =="
    echo "== pull gas-preprocessor base =="

#   $TOOLS => tools $IJK_GASP_UPSTREAM => https://github.com/Bilibili/gas-preprocessor.git

#   => sh tools/pull-repo-base.sh https://github.com/Bilibili/gas-preprocessor.git extra/gas-preprocessor

#   執行當前文件夾下tools文件夾中的pull-repo-base.sh 并且傳入兩個參數(https://github.com/Bilibili/gas-preprocessor.git,extra/gas-preprocessor)下載gas-preprocessor

    sh $TOOLS/pull-repo-base.sh $IJK_GASP_UPSTREAM extra/gas-preprocessor

#   輸出 "== pull ffmpeg base =="
    echo "== pull ffmpeg base =="

#   $TOOLS => tools $IJK_GASP_UPSTREAM => https://github.com/Bilibili/FFmpeg.git IJK_FFMPEG_LOCAL_REPO => extra/ffmpeg

#   => sh tools/pull-repo-base.sh https://github.com/Bilibili/FFmpeg.git extra/ffmpeg

#   執行當前文件夾下tools文件夾中的pull-repo-base.sh 并且傳入兩個參數(https://github.com/Bilibili/FFmpeg.git,extra/ffmpeg),下載FFmpeg
    sh $TOOLS/pull-repo-base.sh $IJK_FFMPEG_UPSTREAM $IJK_FFMPEG_LOCAL_REPO
}

  • 4.3 pull_fork函數功能
    • 1.接收一個平臺架構版本參數,執行pull-repo-ref.sh腳本,這個腳本用于獲取B站托管的github上的FFmpeg分支,根據傳入的不同平臺架構放置不同工作目錄
    • 這個函數會調用四次,每次傳入的參數不一樣,分別是armv7,armv64,i386,x86_64
    • 也就是會執行四次腳本,下次ffmpeg到對應架構平臺的工作目錄
# 定義函數【pull_fork】
function pull_fork() {
#   輸出 平臺架構
    echo "== pull ffmpeg fork $1 =="

#   $TOOLS => tools $IJK_FFMPEG_FORK => https://github.com/Bilibili/FFmpeg.git IJK_FFMPEG_LOCAL_REPO => extra/ffmpeg

#   執行tools文件夾下的pull-repo-ref.sh腳本 并且傳入3個參數 (https://github.com/Bilibili/FFmpeg.git , ios/ffmpeg-平臺架構 ,extra/ffmpeg)

    sh $TOOLS/pull-repo-ref.sh $IJK_FFMPEG_FORK ios/ffmpeg-$1 ${IJK_FFMPEG_LOCAL_REPO}
    
#   進入 ffmpeg-平臺架構文件
    cd ios/ffmpeg-$1
    
#   IJK_FFMPEG_COMMIT => ff3.1--ijk0.6.1--20160824--001

#   git checkout ff3.1--ijk0.6.1--20160824--001 -B ijkplayer

#   切換到ffmpeg版本分支,并且強制創建新的分支ijkplayer,
    git checkout ${IJK_FFMPEG_COMMIT} -B ijkplayer
    
#   回到上一級目錄
    cd -
}
  • 4.4 pull_fork_all函數功能
    • 調用4次pull_fork函數,依次傳入armv7,arm64,i386,x86_64
    • 執行效果
      • pull_fork armv7
      • pull_fork arm64
      • pull_fork i386
      • pull_fork x86_64
# 定義函數【pull_fork_all】
function pull_fork_all() {
    # 變量$FF_ALL_ARCHS =  armv7 arm64 i386 x86_64
    # 遍歷FF_ALL_ARCHS,依次調用pull_fork函數
    for ARCH in $FF_ALL_ARCHS
    do
        pull_fork $ARCH
    done
}

5.執行執行pull_common,pull_fork_all

#   邏輯分支語句
#   FF_TARGET => $1
#   執行腳本的時候,沒有傳任何參數,因此$1 = 空
#   case "$FF_TARGET" in => case "$1" in => case "" in

#   不滿足任何條件,執行 *) 后面的語句(執行pull_common,pull_fork_all函數)

case "$FF_TARGET" in
    ffmpeg-version)
        echo_ffmpeg_version
    ;;
    armv7|armv7s|arm64|i386|x86_64)
        pull_common
        pull_fork $FF_TARGET
    ;;
    all|*)
        pull_common
        pull_fork_all
    ;;
esac

二、分析【pull-repo-base.sh】腳本做的事情

  • pull-repo-base.sh腳本作用 :用于下載B站托管的github上的FFmpeg分支源碼和FFmpeg依賴包
  • 當前腳本會執行二次,分別下載gas-preprocessor和FFmpeg,先下載gas-preprocessor,在下載FFmpeg,因為FFmpeg必須依賴gas-preprocessor

1.接收2個腳本參數

// 下載遠程代碼的地址
// gas-preprocessor => https://github.com/Bilibili/gas-preprocessor.git
// ffmpeg => https://github.com/Bilibili/FFmpeg.git
REMOTE_REPO=$1

// 需要下載的遠程代碼clone到本地的位置(extra/gas-preprocessor,extra/ffmpeg)
LOCAL_WORKSPACE=$2

2.克隆ffmpeg源碼到本地倉庫

  • 2.1 判斷2個參數是否有值
  • 2.2 判斷文件是否存在,一開始都不存在,克隆源碼到本地目錄LOCAL_WORKSPACE
Snip20160827_1.png
  • 2.3 執行 https://github.com/Bilibili/gas-preprocessor.git extra/gas-preprocessor 或者 git clone https://github.com/Bilibili/FFmpeg.git extra/ffmpeg

  • 2.4 執行pull-repo-base.sh腳本后,ijkplayer目錄效果
    
執行腳本后.png
#   判斷2個參數是否有值
if [ -z $REMOTE_REPO -o -z $LOCAL_WORKSPACE ]; then
    echo "invalid call pull-repo.sh '$REMOTE_REPO' '$LOCAL_WORKSPACE'"
#   判斷文件是否存在,一開始都不存在
elif [ ! -d $LOCAL_WORKSPACE ]; then
#   克隆源碼到本地目錄LOCAL_WORKSPACE
    git clone $REMOTE_REPO $LOCAL_WORKSPACE
else
    cd $LOCAL_WORKSPACE
    git fetch --all --tags
    cd -
fi

三、分析【pull-repo-ref.sh】腳本做的事情

  • pull-repo-ref.sh腳本作用:下載B站托管的github上的FFmpeg分支,分別根據不同的架構平臺創建對應的目錄,把ffmpeg源碼放置不同架構平臺的工作目錄中
  •  `平臺架構`:armv7,arm64,i386,x86_64
    
  • 當前腳本會執行四次

1.接收3個腳本參數

// B站自己托管站github的FFmpeg
REMOTE_REPO=https://github.com/Bilibili/FFmpeg.git 

//  本地目標倉庫存放位置,xxx為架構平臺版本(armv7,arm64,i386,x86_64)
LOCAL_WORKSPACE=ios/ffmpeg-xxx 

// 遠程ffmpe官方倉庫clone到本地的位置
REF_REPO=extra/ffmpeg 

2.克隆ffmpeg源碼到本地倉庫

  • 2.1 判斷3個參數字符串是否為空
  • 2.2 判斷文件是否存在,一開始都不存在,克隆ffmpeg源碼到本地倉庫
執行pull-repo-ref.sh腳本前.png
  • 2.3 執行git clone --reference extra/ffmpeg https://github.com/Bilibili/FFmpeg.git ios/ffmpeg-平臺版本
  • 2.4 執行pull-repo-ref.sh腳本后
    
執行pull-repo-ref.sh腳本后.png
#  判斷3個參數字符串是否為空

if [ -z $1 -o -z $2 -o -z $3 ]; then
    echo "invalid call pull-repo.sh '$1' '$2' '$3'"
    
#   判斷文件是否存在,一開始都不存在,所以執行 git clone --reference $REF_REPO $REMOTE_REPO $LOCAL_WORKSPACE

elif [ ! -d $LOCAL_WORKSPACE ]; then
#   git clone --reference extra/ffmpeg https://github.com/Bilibili/FFmpeg.git ios/ffmpeg-armv7
    git clone --reference $REF_REPO $REMOTE_REPO $LOCAL_WORKSPACE
    
#   進入到本地倉庫目錄
    cd $LOCAL_WORKSPACE
    
#   將版本庫未打包的松散對象打包
    git repack -a
else
    cd $LOCAL_WORKSPACE
    git fetch --all --tags
    cd -
fi

3.為什么這里的clone加了--reference參數?

  • git clone --reference來獲取B站得FFmpeg,實際上根據用法介紹,--reference是為了減少從網絡獲取的文件,盡可能從本地的倉庫中獲取;

  • 由于一開始的時候已經獲取了官方ffmpeg代碼,在獲取B站的分支倉庫時就可以將之前下好的官方倉庫的本地庫作為參考倉庫

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容