<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          老生常談-FFmpeg 的編譯問題輕松搞定

          共 3320字,需瀏覽 7分鐘

           ·

          2021-10-28 11:46

          前幾天發(fā)了一篇 FFmpeg 調(diào)用 Android MediaCodec 進行硬解碼 的文章,這里面的技術(shù)點不算太難,也還是調(diào)用 FFmpeg 的常用接口操作,但重點在于 FFmpeg 的版本選擇以及編譯選項要開啟 MediaCodec 才行。

          關于 FFmpeg 的編譯,是個老生常談的話題了,很多初學者都會卡在怎么編譯動態(tài)庫 so 的問題上,這其實也是 Android 開發(fā)轉(zhuǎn)音視頻的一大攔路虎,一行 FFmpeg 代碼都沒來得及寫呢,就得先折騰好久編譯問題。

          當然了,編譯麻煩肯定是 FFmpeg 的鍋。因為它的不斷升級,從早期 2.x 版本到現(xiàn)在的 4.x 版本,調(diào)用接口發(fā)生了變化,編譯選項也調(diào)整了不少,但網(wǎng)上的各種 Android so 動態(tài)庫編譯文章可沒有對應更新哦,有的教程還停留在 2.x 版本上,如果你照著去編譯了,這里面肯定會有兼容性問題的。

          舉幾個例子:

          • FFmpeg 源碼里面的文件要修改嗎?

          早期的編譯版本還要在 FFmpeg 里面修改一些源碼才行,最常見的就是下面的代碼:

          SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
          LIB_INSTALL_EXTRA_CMD='?(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
          SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
          SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'

          以前需要修改編譯后庫名字的連接方式,但是在最新版本中是不用了(最新版指的是 ffmpeg 的 release/4.4 分支版本)。

          另外,在實際編譯中也不需要修改任何 FFmpeg 源碼的。

          • Android NDK 要用哪個版本?

          這也是個常見的兼容性問題。

          選擇 NDK 版本實際上是在選擇編譯器,早先編譯可能用的是 GCC 編譯,后來 Google 在 NDK r18b 版本移除了 GCC 編譯工具,具體可以參考如下鏈接:

          NDK 修訂歷史記錄

          https://developer.android.com/ndk/downloads/revision_history?hl=zh-Cn?

          所以現(xiàn)在最新的動態(tài)庫編譯都是用 Clang 進行操作的,為了跟上時代步伐,也就不要用之前的 NDK 版本了,直接上最新的。


          為了避免大家把精力消耗在 FFmpeg 的編譯上,直接就給出一個 Github Repo ,將編譯腳本都放在這個倉庫上了。

          地址如下:

          https://github.com/glumes/ffmpeg_android

          FFmpeg 編譯

          其中 FFmpeg 源碼是作為該倉庫的一個子模塊 Submodules 的形式加載進來的,在下載時要注意一下:

          git?clone?--recursive?https://github.com/glumes/ffmpeg_android

          下載后,進入到 build_android.sh 文件中,將 NDK 替換成你自己的路徑,最好也用 r20b 版本的,保持一致。

          #!/bin/bash
          ?
          #你的NDK路徑
          NDK=/Users/glumes/Downloads/android-ndk-r20b
          TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
          API=21

          替換后,給腳本可執(zhí)行權(quán)限就能運行了,編譯后的動態(tài)庫在 ffmpeg_library 文件夾中,目前僅編譯了 armeabi-v7a 架構(gòu)的。

          android 文件夾內(nèi)對應加載 so 的 Android 工程,也是 FFmpeg 調(diào)用 Android MediaCodec 的源碼。

          這個工程目錄也是不需要修改 FFmpeg 的,并且關于 FFmpeg 的很多編譯選項開關放在了 config-env.sh 目錄中,有需要可以在文件內(nèi)做修改,目前的選項是開啟了 mediacodec 編碼的,但它的修改不影響主的編譯腳本運行。

          順便貼一下源碼:

          這里是具體執(zhí)行編譯的函數(shù),函數(shù)用到的一些參數(shù)要在外面定義好:

          function?build_android
          {
          echo?"Compiling?FFmpeg?for?$CPU"

          ./configure?\
          ????--prefix=$PREFIX?\
          ????--libdir=$LIB_DIR?\
          ????--enable-shared?\
          ????--disable-static?\
          ????--enable-jni?\
          ????--disable-doc?\
          ????--disable-symver?\
          ????--disable-programs?\
          ????--target-os=android?\
          ????--arch=$ARCH?\
          ????--cpu=$CPU?\
          ????--cc=$CC?\
          ????--cxx=$CXX?\
          ????--enable-cross-compile?\
          ????--sysroot=$SYSROOT?\
          ????--extra-cflags="-Os?-fpic?$OPTIMIZE_CFLAGS"?\
          ????--extra-ldflags="$ADDI_LDFLAGS"?\
          ????--disable-asm?\
          ????#?這些編譯參數(shù)在?config-env.sh?文件中定義了
          ????$COMMON_FF_CFG_FLAGS
          make?clean
          make?-j8?#?這里是定義用幾個CPU編譯
          make?install
          echo?"The?Compilation?of?FFmpeg?for?$CPU?is?completed"
          }

          接下來定義好相關參數(shù),就可以執(zhí)行了:

          //?編譯的?configure?可執(zhí)行文件在?ffmpeg?源碼目錄中,要先進入到目錄里
          cd?ffmpeg

          //?定義好編譯的架構(gòu)
          OUTPUT_FOLDER="armeabi-v7a"
          ARCH="arm"
          CPU="armv7-a"
          TOOL_CPU_NAME=armv7a
          TOOL_PREFIX="$TOOLCHAIN/bin/arm-linux-androideabi"
          ?
          CC="$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang"
          CXX="$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++"
          SYSROOT="$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot"
          PREFIX="${PWD}/../ffmpeg_library/android/$OUTPUT_FOLDER"
          LIB_DIR="${PWD}/../ffmpeg_library/android/libs/$OUTPUT_FOLDER"
          OPTIMIZE_CFLAGS="-march=$CPU"
          build_android

          由于我們的編譯腳本不放在 FFmpeg 源碼目錄中,所以要對路徑做一些修改,這樣可以絕對地不改動任何 FFmpeg 內(nèi)容了。

          通過上述的參數(shù)設定,應該就可以編譯出正確的 Android 動態(tài)庫了,如果你在編譯過程中有任何問題,歡迎加我微信 ezglumes 聯(lián)系我,及時調(diào)整保證輕松搞定編譯過程


          技術(shù)交流,歡迎加我微信:ezglumes ,拉你入技術(shù)交流群。

          推薦閱讀:

          音視頻開發(fā)工作經(jīng)驗分享 || 視頻版

          OpenGL ES 學習資源分享

          開通專輯 | 細數(shù)那些年寫過的技術(shù)文章專輯

          NDK 學習進階免費視頻來了

          你想要的音視頻開發(fā)資料庫來了

          推薦幾個堪稱教科書級別的 Android 音視頻入門項目

          覺得不錯,點個在看唄~

          瀏覽 48
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日日骚av一区二区三区 | 久操21| 99久久亚洲精品日本无码 | 亚洲AV黄片 | 国产免费无码视频 |