background
Nowadays, FFmpeg is more and more widely used, and more and more application scenarios. If you want to use FFmpeg on the Android platform, you must first master the skills of cross-compilation, so as to compile a good FFmpeg library on the Android platform. FFmpeg is a multimedia development framework that supports audio and video one-stop services.
- FFmpeg provides only the framework and the necessary tools. Some of the tool toolkit relies on third-party inheritance, but FFmpeg provides some common interfaces for developers to integrate.
- FFmpeg is compiled natively without HTTPS parsing and requires the introduction of a third-party library to solve the HTTPS identification problem. This third-party library is openSSL
- Do you need to integrate H265? At present, H265 has poor performance in the soft solution of Android, and there is basically no possibility of commercial application. Therefore, it is not meaningful to integrate X265 into FFmpeg, which will not be discussed in this paper.
Compilation prepared
Download FFmpeg source: git.ffmpeg.org/ffmpeg.git after switch to a release branch, I switch n4.0.3 branch; Each branch of the compilation situation is different, this branch code try to compile can be, recommended to everyone;
Build system: Mac OS X or Ubuntu 18.04
NDK version: Android-NDK-R14b
You can directly refer to my open source project: github.com/JeffMony/An…
Download this open source project, where the ffMPEG directory has the specific FFMPEG source code. Of course you can also download the ffMPEG source code separately.
FFmpeg is compiled separately
So what we want to do now is generate FFmpeg so to execute on an Android phone, and there’s a very important file in FFmpeg which is configure for Android, Just focus on armeabi-V7A, ARM64-V8A, x86, and X86_64. There are four main points of cross-compilation:
- The compiler architecture ARCH, Armeabi-V7A is ARM, ARM64-V8A is ARM64, x86 architecture is x86, and x86_64 is X86_64
- Armeabi-v7a is arm-linux-Androideabi, arm64-v8a is AARCH64-linux-Android, x86 is i686-linux-Android, X86_64 is x86_64_linux_android, this is still a little different from cognition.
- System link SYSROOT armeabi – v7a is $NDK_ROOT/platforms/android – $API/arch – arm /, Arm64 – v8a is $NDK_ROOT/platforms/android – $API/arch – arm64 / x86 is $NDK_ROOT/platforms/android – $API/arch – x86 /, X86_64 is $NDK_ROOT/platforms/android – $API/arch – x86_64 /
- $NDK_ROOT/toolchains/$platform-4.9 /prebuilt/darwin-x86_64/bin/$PLATFORM-, $NDK_ROOT/toolchains/$PLATFORM- $NDK_ROOT/ Toolchains /$platform-4.9 /prebuilt/linux-x86_64/bin/$PLATFORM
The NDK toolchains directory contains cross-compiled toolsets:
Drwxr-xr-x 3 Jeffmony 4096 March 15 2017 Aarch64-linux-Android-4.9 DrwxR-xR-x 3 Jeffmony 4096 March 15 2017 Arm-linux-androideabi-4 DrwxR-xR-x 3 Jeffmony mony 4096 March 15 2017 DRwxR-xR-x 3 Jeffmony 4096 March 15 2017 DrwxR-xR-x 3 Jeffmony 4096 March 15 2017 Mips64el-Linux-Android 3 Drwxr-xr-x 3 Jeffmony mony 4096 March 15 2017 Mipsel-Linux-Android 3 DrwxR-xR-x 3 3月 15 2017 DrwxR-xR-x 3 DrwxR-xR-x 3 Jeffmony jeffmony 4096 March 15 2017 x86_64-4.9Copy the code
There are many configure options for FFmpeg. You can see them all with./configure –help. Note that if you want to generate the standard SO naming convention, you need to change the configuration in the configure file. 1. Configure change point 1
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)
Copy the code
Modified to
SLIBNAME_WITH_MAJOR='$(SLIBNAME)-$(LIBMAJOR)$(SLIBSUF)'
Copy the code
2. Configure modify 2
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
Copy the code
Modified to
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
Copy the code
Here is the complete compiled script for ffMPEG’s dynamic library: it supports both MAC and Linux platforms
#! /bin/bash # PLATFORM -----> MAC LINUX COMPILE_PLATFORM="LINUX" build_arm() { API=24 ARCH=$1 PLATFORM=$2 if [ "$COMPILE_PLATFORM" = = "MAC"] then export NDK_ROOT = / Users/jeffmony/tools/android - the NDK - the NDK r14b # change their local path SYSROOT=$NDK_ROOT/platforms/android-$API/arch-$ARCH/ CROSS_PREFIX = $NDK_ROOT toolchains / $PLATFORM - 4.9 / prebuilt/Darwin - x86_64 / bin / $PLATFORM - the else export NDK_ROOT = / home/jeffmony/developer/android - the NDK - r14b/android - the NDK - the NDK r14b # change their local path SYSROOT=$NDK_ROOT/platforms/android-$API/arch-$ARCH/ CROSS_PREFIX = $NDK_ROOT toolchains / $PLATFORM - 4.9 / prebuilt/Linux - x86_64 / bin / $PLATFORM - fi $(PWD)/android/openssl_lib/$ARCH =$(PWD)/android/openssl_lib/$ARCH echo "$(PWD)/android/openssl_lib/$ARCH echo" ./configure \ --prefix=$PREFIX \ --disable-doc \ --enable-shared \ --disable-static \ --disable-x86asm \ --disable-asm \ --disable-symver \ --disable-devices \ --disable-avdevice \ --enable-gpl \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --enable-small \ --enable-nonfree \ --enable-cross-compile \ --cross-prefix=$CROSS_PREFIX \ --target-os=android \ --arch=$ARCH \ --sysroot=$SYSROOT } build_arm arm arm-linux-androideabi make clean make -j4 make Install echo "install ffmpeg $ARCH..." Build_arm arm64 aarch64-linux-android make clean make -j4 make install echo "build ffmpeg $ARCH" build_x86() { API=24 ARCH=$1 PLATFORM=$2 if [ "$COMPILE_PLATFORM" == "MAC" ] then export NDK_ROOT = / Users/jeffmony/tools/android - the NDK - r14b # change their local the NDK SYSROOT path = $NDK_ROOT/platforms/android - $$arch/API/arch - CROSS_PREFIX = $NDK_ROOT toolchains / $ARCH - 4.9 / prebuilt/Darwin - x86_64 / bin / $PLATFORM - the else export NDK_ROOT = / home/jeffmony/developer/android - the NDK - r14b/android - the NDK - the NDK r14b # change their local path SYSROOT=$NDK_ROOT/platforms/android-$API/arch-$ARCH/ CROSS_PREFIX = $NDK_ROOT toolchains / $ARCH - 4.9 / prebuilt/Linux - x86_64 / bin / $PLATFORM - fi $(PWD)/android/openssl_lib/$ARCH =$(PWD)/android/openssl_lib/$ARCH echo "$(PWD)/android/openssl_lib/$ARCH echo" ./configure \ --prefix=$PREFIX \ --disable-doc \ --enable-shared \ --disable-static \ --disable-x86asm \ --disable-asm \ --disable-symver \ --disable-devices \ --disable-avdevice \ --enable-gpl \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --enable-small \ --enable-nonfree \ --enable-cross-compile \ --cross-prefix=$CROSS_PREFIX \ --target-os=android \ --arch=$ARCH \ --sysroot=$SYSROOT } build_x86 x86 i686-linux-android make clean make -j4 make Install echo "install ffmpeg $ARCH..." build_x86 x86_64 x86_64-linux-android make clean make -j4 make installCopy the code
Put the script in the FFmpeg project file, execute the script, execute FFmpeg/Android directory to generate two folders, respectively arm and ARM64, inside the files are the two CPU architecture generated dynamic library and header files;
- Below include are generated headers that reference the functionality of the ffMPEG specific module in the generate SO;
- The pkgconfig folder is a link file on the PC, so we can ignore it here.
- Below the share folder are examples of ffMPEG applications. Learning these examples is very helpful to understand FFMPEG.
The generated file directory is as follows:
├ ─ ─ arm │ ├ ─ ─ the include │ ├ ─ ─ lib │ └ ─ ─ share ├ ─ ─ arm64 │ ├ ─ ─ the include │ ├ ─ ─ lib │ └ ─ ─ share ├ ─ ─ x86 │ ├ ─ ─ the include │ ├ ─ ─ Lib │ └ ─ ─ share └ ─ ─ x86_64 ├ ─ ─ the include ├ ─ ─ lib └ ─ ─ shareCopy the code
However, the generated SO also has some defects, that is, it cannot access HTTPS links, which of course cannot be received on the Android platform, so it still needs to add SUPPORT for HTTPS.
Openssl compiled
Openssl is a comprehensive library that supports HTTPS. To support HTTPS, FFMPEG needs to integrate the OpenSSL library, so we compile the OpenSSL library to generate the static library, and then integrate it into ffMPEG’s SO. To download the openssl library, www.openssl.org/source/snap… Download the latest: OpenSSL-1.1.1-stables – snap-20200215.tar. gz openSSL library compilation configuration is./Configure file
Configuring OpenSSL Version 1.1.1l-dev (0x101010c0L) for os-specific seed configuration Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]Copy the code
We need to compile OpenSSL into FFMPEG, or choose to compile the static library for easy packaging. Compile the script as follows
#! /bin/bash # PLATFORM -----> MAC LINUX COMPILE_PLATFORM="LINUX" build() { API=24 CPU=$1 PLATFORM=$2 make clean rm -rf $(pwd)/android/$CPU if [ "$COMPILE_PLATFORM" == "MAC" ] then export NDK_ROOT=/Users/jeffmony/tools/android-ndk-r14b # Change the local NDK path export ANDROID_NDK_HOME=$NDK_ROOT PATH = $ANDROID_NDK_HOME toolchains / $PLATFORM - 4.9 / prebuilt/Darwin - x86_64 / bin: $PATH else export NDK_ROOT = / home/jeffmony/developer/android - the NDK - r14b/android - the NDK - the NDK r14b # change their local path export ANDROID_NDK_HOME = $NDK_ROOT PATH = $ANDROID_NDK_HOME toolchains / $4.9 / prebuilt/Linux PLATFORM - - x86_64 / bin: $PATH fi. / Configure the android - $CPU -D__ANDROID_API__=24 no-shared no-ssl2 no-ssl3 no-comp no-hw no-engine --prefix=$(pwd)/android/$CPU --openssldir=$(pwd)/android/$CPU make make install } # build armv7 build arm arm-linux-androideabi # build armv8 build arm64 aarch64-linux-android # build x86 build x86 x86 # build x86_64 build x86_64 x86_64Copy the code
After compiling, four folders, arm, ARM64, x86 and X86_64, will be generated in the Android folder.
DRWXRWXR - x 2 jeffmony jeffmony on June 9, 4096, bin, yea DRWXRWXR - x 2 jeffmony jeffmony on June 9, 4096, certs, yea - rw - r - r - 1 Jeffmony jeffmony on June 9, 412. 10:32 ct_log_list CNF - rw - r - r - 1 jeffmony jeffmony 412 on June 9. 10:32 ct_log_list CNF. Dist 6月 9 10:32 lib drwxrwxr-x 2 drwxrwxr-x 3 Jeffmony 4096 6月 9 10:32 include drwxrwxr-x 4 Jeffmony 4096 6月 9 10:32 lib DrwxrwxR-x 2 drwxrwxr-x 3 Jeffmony 4096 6月 9 10:32 include Drwxrwxr-x 4 Jeffmony 4096 6月 9 10:32 lib DrwxrwxR-x 2 Jeffmony jeffmony 4096 June 9 but misc - rw - r - r - 1 jeffmony jeffmony 10909 on June 9. 10:32 openssl CNF jeffmony - rw - r - r - 1 6月 9 10:32 openssl.cnF. Dist drwxrwxR-x 2 jeffmony 1096 6月 9 10:32 private DRwXrwxR-x 4 Jeffmony 1096 6月 9 10:32 openssl.cnF Jeffmony 4096 June 9 10:33 shareCopy the code
- Below include is the openSSL core header;
- Below lib is the compiled static library; Libcrypto. A and libssl. A
With the OpenSSL static library generated, the next step is to integrate the static library into the ffMPEG compiler.
FFmpeg compilation introduces the OpenSSL library
If you want to parse HTTPS links, you must compile openSSL into the FFMPEG library.
To compile ffMpeg, add some parameters:
- Add –enable-openssl \ –enable-nonfree to the compilation configuration
- Add openSSL link to compile link: -extra-cflags add openSSL header; –extra-ldflags + openSSL static library;
#! /bin/bash # PLATFORM -----> MAC LINUX COMPILE_PLATFORM="LINUX" build_arm() { API=24 ARCH=$1 PLATFORM=$2 OPENSSL=$(pwd)/openssl_lib/$ARCH if [ "$COMPILE_PLATFORM" == "MAC" ] then export NDK_ROOT = / Users/jeffmony/tools/android - the NDK - r14b # change their local the NDK SYSROOT path = $NDK_ROOT/platforms/android - $$arch/API/arch - CROSS_PREFIX = $NDK_ROOT toolchains / $PLATFORM - 4.9 / prebuilt/Darwin - x86_64 / bin / $PLATFORM - the else export NDK_ROOT = / home/jeffmony/developer/android - the NDK - r14b/android - the NDK - the NDK r14b # change their local path SYSROOT=$NDK_ROOT/platforms/android-$API/arch-$ARCH/ CROSS_PREFIX = $NDK_ROOT toolchains / $PLATFORM - 4.9 / prebuilt/Linux - x86_64 / bin / $PLATFORM - fi $(PWD)/android/openssl_lib/$ARCH =$(PWD)/android/openssl_lib/$ARCH echo "$(PWD)/android/openssl_lib/$ARCH echo" ./configure \ --prefix=$PREFIX \ --disable-doc \ --enable-shared \ --disable-static \ --disable-x86asm \ --disable-asm \ --disable-symver \ --disable-devices \ --disable-avdevice \ --enable-gpl \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --enable-small \ --enable-openssl \ --enable-nonfree \ --enable-cross-compile \ --cross-prefix=$CROSS_PREFIX \ --target-os=android \ --arch=$ARCH \ --sysroot=$SYSROOT \ --extra-cflags="-I$OPENSSL/include -fPIE -pie" \ --extra-ldflags="-L$OPENSSL/lib" } build_arm arm arm-linux-androideabi Make clean make -j4 make install echo "make ffmpeg $ARCH..." Build_arm arm64 aarch64-linux-android make clean make -j4 make install echo "build ffmpeg $ARCH" build_x86() { API=24 ARCH=$1 PLATFORM=$2 OPENSSL=$(pwd)/openssl_lib/$ARCH if [ "$COMPILE_PLATFORM" == "MAC" ] then Export NDK_ROOT = / Users/jeffmony/tools/android - the NDK - the NDK r14b # change their local path SYSROOT=$NDK_ROOT/platforms/android-$API/arch-$ARCH/ CROSS_PREFIX = $NDK_ROOT toolchains / $ARCH - 4.9 / prebuilt/Darwin - x86_64 / bin / $PLATFORM - the else export NDK_ROOT = / home/jeffmony/developer/android - the NDK - r14b/android - the NDK - the NDK r14b # change their local path SYSROOT=$NDK_ROOT/platforms/android-$API/arch-$ARCH/ CROSS_PREFIX = $NDK_ROOT toolchains / $ARCH - 4.9 / prebuilt/Linux - x86_64 / bin / $PLATFORM - fi $(PWD)/android/openssl_lib/$ARCH =$(PWD)/android/openssl_lib/$ARCH echo "$(PWD)/android/openssl_lib/$ARCH echo" ./configure \ --prefix=$PREFIX \ --disable-doc \ --enable-shared \ --disable-static \ --disable-x86asm \ --disable-asm \ --disable-symver \ --disable-devices \ --disable-avdevice \ --enable-gpl \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --enable-small \ --enable-openssl \ --enable-nonfree \ --enable-cross-compile \ --cross-prefix=$CROSS_PREFIX \ --target-os=android \ --arch=$ARCH \ --sysroot=$SYSROOT \ --extra-cflags="-I$OPENSSL/include -fPIE -pie" \ --extra-ldflags="-L$OPENSSL/lib" } build_x86 x86 i686-linux-android Make clean make -j4 make install echo "make ffmpeg $ARCH..." build_x86 x86_64 x86_64-linux-android make clean make -j4 make installCopy the code
The following error occurred during compilation. Openssl cannot be found.
Check it out in the ffmpeg/configure file:
The error is here because the new openSSL version needs to add a new check statement to configure:
check_lib openssl openssl/ssl.h OPENSSL_init_ssl -lssl -lcrypto
Copy the code
Older OpenSSL libraries are initialized with ‘SSL_library_init’, while newer versions of OpenSSL are initialized with ‘OPENSSL_init_ssl’;
The following normal compilation is no problem; The generated FFMPEG so can parse HTTPS;
So compiled in the above way can parse HTTPS protocol. How to use these SO, you can refer to the open source project, simple test whether the compiled SO can be used: github.com/JeffMony/Je…