FFmpeg和OpenSSL的編譯與使用

引言

目前在學習FFmpeg的使用,肯定是要從源碼編譯開始一步步摸啦,編譯過程中也是遇到了大大小小很多問題,查到的資料基本也都是比較老舊的版本,經(jīng)過各種試錯吧,終于是編譯成功了,現(xiàn)在就來記錄一下編譯的過程,也希望能幫助到看這篇文章的你。


源碼與環(huán)境

編譯安卓系統(tǒng)使用的庫,需要用到NDK的工具鏈進行交叉編譯,我們這里使用的是 r20b 版本。
還有就是需要下載的源碼了,包括 FFmpeg 和 OpenSSL 的源代碼,我們直接去官網(wǎng)下載最新的版本。
NDK歷史版本:https://developer.android.google.cn/ndk/downloads/revision_history
FFmpeg源碼:http://www.ffmpeg.org/download.html
OpenSSL源碼:https://www.openssl.org/source/snapshot/


準備編譯腳本

哎呀,現(xiàn)在還沒有時間寫詳細介紹,就先把腳本直接貼到這里吧。挖個坑,后面有時間再補,放個狗頭保命??

OpenSSL腳本

當然如果你不需要支持https,就可以跳過openssl,直接去編譯ffmpeg。

#!/bin/bash
set -x

# NDK的路徑,根據(jù)自己的NDK位置進行設置
export ANDROID_NDK_ROOT=/Users/xxx/env/android-sdk/ndk/android-ndk-r20b
# 編譯工具鏈路徑
TOOLCHAIN=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64
# 編譯環(huán)境
SYSROOT=$TOOLCHAIN/sysroot

# 目標Android版本
API=21
# 目標指令集
ARCH=NONE
#so庫輸出目錄
OUTPUT_DIR=NONE

function build_armv7a() {
  ARCH=android-arm
  OUTPUT_DIR=$PWD/outputs/armeabi-v7a

  build_one
}

function build_aarch64() {
  ARCH=android-arm64
  OUTPUT_DIR=$PWD/outputs/arm64-v8a

  build_one
}

function build_one() {
  CC=clang
  export PATH=$TOOLCHAIN/bin:$PATH

  ./configure \
  $ARCH \
  -D__ANDROID_API__=$API \
  --prefix=$OUTPUT_DIR

  make clean all
  # 這里是定義用幾個CPU編譯
  make -j12
  make install
}

# 懶,就這么寫吧,編哪個就放開哪個
build_armv7a
#build_aarch64

放在OpenSSL源碼更目錄下,命令行進入文件夾并執(zhí)行該腳本,成功后會在當前目錄下生成如下目錄,需要用到的頭文件和靜態(tài)、動態(tài)庫,就在對應的 include 和 lib 文件夾下。


剛截的圖,還熱乎.jpg

FFmpeg腳本

#!/bin/bash
set -x

# NDK的路徑,根據(jù)自己的NDK位置進行設置
NDK=/Users/wwf/Desktop/env/android-sdk/ndk/android-ndk-r20b
# 編譯工具鏈路徑
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
# 編譯環(huán)境
SYSROOT=$TOOLCHAIN/sysroot

# 目標Android版本
API=21
# 目標指令集
ARCH=NONE
#so庫輸出目錄
OUTPUT_DIR=NONE
# 交叉編譯命令前綴
CROSS_PREFIX=NONE
CROSS_PREFIX_CLANG=NONE

# 若不添加 openssl 支持,這項不需要配置
OPENSSL_DIR=NONE

function build_armv7a() {
  ARCH=arm
  OUTPUT_DIR=$PWD/outputs/armeabi-v7a
  CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
  CROSS_PREFIX_CLANG=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-

  OPENSSL_DIR=$PWD/openssl/armeabi-v7a

  del_temp_config
  build_one
}

function build_aarch64() {
  ARCH=aarch64
  OUTPUT_DIR=$PWD/outputs/arm64-v8a
  CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
  CROSS_PREFIX_CLANG=$TOOLCHAIN/bin/aarch64-linux-android$API-

  OPENSSL_DIR=$PWD/openssl/arm64-v8a

  del_temp_config
  build_one
}

function del_temp_config {
    rm -rf config_components.h
    rm -rf config.h
}

function build_one() {
  ./configure \
  --prefix=$OUTPUT_DIR \
  --target-os=android \
  --arch=$ARCH \
  --enable-asm \
  --enable-neon \
  --enable-cross-compile \
  --enable-shared \
  --disable-static \
  --disable-doc \
  --disable-ffplay \
  --disable-ffprobe \
  --disable-symver \
  --disable-ffmpeg \
  --sysroot=$SYSROOT \
  --cc=${CROSS_PREFIX_CLANG}clang \
  --cxx=${CROSS_PREFIX_CLANG}clang++ \
  --cross-prefix=$CROSS_PREFIX \
  --enable-openssl \
  --enable-protocols \
  --enable-protocol=https \
  --enable-nonfree \
  --extra-cflags="-I$OPENSSL_DIR/include -fPIC" \
  --extra-ldflags="-L$OPENSSL_DIR/lib -lssl -lcrypto" \
# 若不添加 openssl 支持,上面幾項不需要配置,替換成下面這句
#  --extra-cflags="-fPIC"

  make clean all
  # 這里是定義用幾個CPU編譯
  make -j12
  make install
}

# 懶,就這么寫吧,編哪個就放開哪個
build_armv7a
#build_aarch64

其中與openssl相關的部分就是 --enable-openssl 及后面的幾句,作用是允許使用openssl和執(zhí)行要鏈接的頭文件和靜態(tài)庫路徑。
如果不需要鏈接編譯 openssl 的話,腳本中的這一部分就是這樣的:

function build_one() {
  ./configure \
  --prefix=$OUTPUT_DIR \
  ...... 忽略部分 ......
  --cross-prefix=$CROSS_PREFIX \
  --extra-cflags="-fPIC" \

  make clean all
  # 這里是定義用幾個CPU編譯
  make -j12
  make install
}

安卓項目使用與 CMakeList 編寫

還是這句話,直接把腳本貼上吧,有時間在補充詳細說明。

# 最低版本支持
cmake_minimum_required(VERSION 3.18.1)

# 項目名,就是編譯后生成的 so 庫名字
project("ffmpegdemo")

# 支持gnu++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")

# 1. 添加頭文件目錄, 定義so庫和頭文件所在目錄
include_directories(${CMAKE_SOURCE_DIR}/ffmpeg/include)
set(lib_dir ${CMAKE_SOURCE_DIR}/ffmpeg/lib/${ANDROID_ABI})

add_library( avcodec
        SHARED
        IMPORTED )
set_target_properties( avcodec
        PROPERTIES IMPORTED_LOCATION
        ${lib_dir}/libavcodec.so )
add_library( avfilter
        SHARED
        IMPORTED )
set_target_properties( avfilter
        PROPERTIES IMPORTED_LOCATION
        ${lib_dir}/libavfilter.so )
add_library( avformat
        SHARED
        IMPORTED )
set_target_properties( avformat
        PROPERTIES IMPORTED_LOCATION
        ${lib_dir}/libavformat.so )
add_library( avutil
        SHARED
        IMPORTED )
set_target_properties( avutil
        PROPERTIES IMPORTED_LOCATION
        ${lib_dir}/libavutil.so )
add_library( swresample
        SHARED
        IMPORTED )
set_target_properties( swresample
        PROPERTIES IMPORTED_LOCATION
        ${lib_dir}/libswresample.so )
add_library( swscale
        SHARED
        IMPORTED )
set_target_properties( swscale
        PROPERTIES IMPORTED_LOCATION
        ${lib_dir}/libswscale.so )
add_library( avdevice
        SHARED
        IMPORTED )
set_target_properties( avdevice
        PROPERTIES IMPORTED_LOCATION
        ${lib_dir}/libavdevice.so )

add_library( ssl
        SHARED
        IMPORTED )
set_target_properties( ssl
        PROPERTIES IMPORTED_LOCATION
        ${lib_dir}/libssl.so )
add_library( crypto
        SHARED
        IMPORTED )
set_target_properties( crypto
        PROPERTIES IMPORTED_LOCATION
        ${lib_dir}/libcrypto.so )

# 當前cmake文件所在目錄下搜索所有源碼文件,命名為 SRC_LIST 供下面使用
aux_source_directory(. SRC_ROOT)
aux_source_directory(./audiosample SRC_AUDIO)
add_library( # Sets the name of the library.
        ffmpegdemo

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        ${SRC_ROOT}
        ${SRC_AUDIO}
        # native-lib.cpp
        )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
        ffmpegdemo

        # ffmpeg
        avcodec
        avfilter
        avformat
        avutil
        swresample
        swscale
        avdevice
        ssl
        crypto

        OpenSLES
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

這里再貼一下我的目錄結構吧,這些東西怎么放其實都無所謂,主要是要跟 gradle 和 cmake 文件中用到的路徑對得上號。


剛截的圖,熱乎.jpg

先寫到這里吧,沒有詳細說明很是慚愧,后面有時間一定補上。

轉(zhuǎn)載請注明出處,@via FFmpeg和OpenSSL的編譯與使用 蟹蟹。
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容