FFmpeg和OpenSSL的编译与使用

引言

目前在学习FFmpeg的使用,肯定是要从源码编译开始一步步摸啦,编译过程中也是遇到了大大小小很多问题,查到的资料基本也都是比较老旧的版本,经过各种试错吧,终于是编译成功了,现在就来记录一下编译的过程,也希望能帮助到看这篇文章的你。


源码与环境

编译安卓系统使用的库,需要用到NDK的工具链进行交叉编译,我们这里使用的是 r20b 版本。
还有就是需要下载的源码了,包括 FFmpeg 和 OpenSSL 的源代码,我们直接去官网下载最新的版本。
NDK历史版本:https://developer.android.google.cn/ndk/downloads/revision_history
FFmpeg源码:http://www.ffmpeg.org/download.html
OpenSSL源码:https://www.openssl.org/source/snapshot/


准备编译脚本

哎呀,现在还没有时间写详细介绍,就先把脚本直接贴到这里吧。挖个坑,后面有时间再补,放个狗头保命

OpenSSL脚本

当然如果你不需要支持https,就可以跳过openssl,直接去编译ffmpeg。

#!/bin/bash
set -x

# NDK的路径,根据自己的NDK位置进行设置
export ANDROID_NDK_ROOT=/Users/xxx/env/android-sdk/ndk/android-ndk-r20b
# 编译工具链路径
TOOLCHAIN=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64
# 编译环境
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源码更目录下,命令行进入文件夹并执行该脚本,成功后会在当前目录下生成如下目录,需要用到的头文件和静态、动态库,就在对应的 include 和 lib 文件夹下。


刚截的图,还热乎.jpg

FFmpeg脚本

#!/bin/bash
set -x

# NDK的路径,根据自己的NDK位置进行设置
NDK=/Users/wwf/Desktop/env/android-sdk/ndk/android-ndk-r20b
# 编译工具链路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
# 编译环境
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和执行要链接的头文件和静态库路径。
如果不需要链接编译 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

先写到这里吧,没有详细说明很是惭愧,后面有时间一定补上。

转载请注明出处,@via FFmpeg和OpenSSL的编译与使用 蟹蟹。

你可能感兴趣的:(FFmpeg和OpenSSL的编译与使用)