Android Studio 3.3.1 下FFMPEG-3.4.5编译armv7-a SO库

ffmpeg编译的文章很多了,理论上没必要写了,可是架不住Android Studio在不断升级,Android Studio 3.3.1版本,这个版本不允许你只编译arm版本的so库了,所以这个文章目标编译armv7-a。

为什么要编译armv7-a,百度吧,为了apk大小和兼容性,放armv7-a比较合适。

ndk 是android-ndk-r14b 从NDK r18b开始删除了gcc,用clang替换了,所以用这套脚本是不能成功的,最后一个支持gcc的版本是r17c。(18开始gcc被删除用一个脚本替换指向到了llvm目录下的clang,由于这个兼容脚本没用19就删除掉了)

后续更新:使用r20b来编译,请拉到本文最后。

android-ndk-r14b 放到/usr/ndk/android-ndk-r14b,修改权限。

在FFMPEG-3.4.5目录下新建build_android.sh,改可执行。


#!/bin/bash

# 设置NDK路径

NDK=/usr/ndk/android-ndk-r14b

# 设置编译针对的平台,可以根据实际需求进行设置

# 当前设置为最低支持android-14版本,arm架构

SYSROOT=$NDK/platforms/android-14/arch-arm

# 设置编译工具链,4.9为版本号

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64

function build_one

{

./configure \

    --enable-cross-compile \

    --enable-shared \

    --disable-static \

    --disable-doc \

    --disable-ffmpeg \

    --disable-ffplay \

    --disable-ffprobe \

    --disable-ffserver \

    --disable-avdevice \

    --disable-doc \

    --disable-symver \

    --prefix=$PREFIX \

    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \

    --target-os=android \

    --arch=arm \

    --sysroot=$SYSROOT \

    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \

$ADDITIONAL_CONFIGURE_FLAG

make clean

make

make install

}

# 设置编译后文件的输出目录

CPU=armv7-a

PREFIX=$(pwd)/android/$CPU

ADDI_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"

build_one

后面就可以用这个脚本编译了,编译20分钟左右,看你的CPU速度了,多核cpu的可以把倒数第8行的make 改make -j4 多进程跑,加速。

这个里面比较容易出错的地方就是,如果你按网上以前的教程,那些教程都是教你编译arm版本的,机械替换arm到armv7-a 是不能成功的,关键就在于 --extra-cflags里ADDI_CFLAGS 这个flag的设置,设置好了就可以编译成功,在当前目录下的android里,脚本已经设置过了,所以只有so、头文件、例子。

as截图

CPP下新建inlude把头文件拷贝过来,新建jniLibs/armeabi-v7a把so拷贝过来。

还是android studio 3.3.1的改动,CMakeLists改到CPP目录下了,所以层级目录就是以cpp为工程目录,又是一个坑人的地方。


# For more information about using CMake with Android Studio, read the

# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

set(JNI_LIBS_DIR ${CMAKE_SOURCE_DIR}/../jniLibs)

message("JNI_LIBS_DIR:"${JNI_LIBS_DIR})

add_library(avutil

SHARED

        IMPORTED)

set_target_properties(avutil

PROPERTIES IMPORTED_LOCATION

        ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavutil.so)

add_library(swresample

SHARED

        IMPORTED)

set_target_properties(swresample

PROPERTIES IMPORTED_LOCATION

        ${JNI_LIBS_DIR}/${ANDROID_ABI}/libswresample.so)

add_library(swscale

SHARED

        IMPORTED)

set_target_properties(swscale

PROPERTIES IMPORTED_LOCATION

        ${JNI_LIBS_DIR}/${ANDROID_ABI}/libswscale.so)

add_library(avcodec

SHARED

        IMPORTED)

set_target_properties(avcodec

PROPERTIES IMPORTED_LOCATION

        ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavcodec.so)

add_library(avformat

SHARED

        IMPORTED)

set_target_properties(avformat

PROPERTIES IMPORTED_LOCATION

        ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavformat.so)

add_library(avfilter

SHARED

        IMPORTED)

set_target_properties(avfilter

PROPERTIES IMPORTED_LOCATION

        ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavfilter.so)

include_directories(./include)

aux_source_directory(. NATIVE_SRC)

# Creates and names a library, sets it as either STATIC

# or SHARED, and provides the relative paths to its source code.

# You can define multiple libraries, and CMake builds them for you.

# Gradle automatically packages shared libraries with your APK.

add_library(# Sets the name of the library.

        native-lib

        # Sets the library as a shared library.

        SHARED

        # Provides a relative path to your source file(s).

#        native-lib.cpp)

        ${NATIVE_SRC})

# 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)

find_library(android-lib

        android )

# 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.

        native-lib

avutil

swresample

swscale

avcodec

avformat

avfilter

        ${android-lib}

        # Links the target library to the log library

# included in the NDK.

        ${log-lib})

CMakeLists 的内容如上

native-lib.cpp

导入

extern "C" {

#include "include/libavcodec/avcodec.h"

#include "include/libavfilter/avfilter.h"

#include "include/libswscale/swscale.h"

#include "include/libavformat/avformat.h"

#include "include/libavutil/avutil.h"

#include "include/libswresample/swresample.h"

}

activity里导入库


companion object {

    // Used to load the 'native-lib' library on application startup.

    init {

System.loadLibrary("native-lib")

}

}

还有一个设置,指定模块只编译armeabi-v7a,因为我们编译的native-lib依赖的so都是arm-v7a格式的,在XXX.gradle设置。

defaultConfig {
//skip
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11"
            }
            ndk {
                abiFilters  'armeabi-v7a'
            }
        }
    }

主要是讲和以前版本的不同,看不懂请找几个老版本的参考,有一些博客明明编译的是arm版本,直接集成到armv7a里使用,我也不确定这样有没有问题,v7a的体积会相对小一点,也是个优点了。

更新NDK r20B的编译方法

在17之后,18开始就删除了gcc,上面的脚本指定到gcc编译器是没有用的。
18的gcc编译器,是一个指向clang的脚本,根本没用,在19干脆就删掉了这个脚本。
18和19的clang编译器那边结构还不一样,clang需要指定编译器的脚本名,因为脚本是由platform+后缀+api版本来编写的,所以还是直接用最新的20b版本好了,使用18版本需要你自己配bulid脚本。

总结:要么17c使用gcc编译,要么直接20b配clang,别搞18版本浪费时间

换了R20B后发现,再编译3.3.1有编译错误了,可能是需要更新ffmpeg版本了,测试了一下3.4.7、4.1都是可以的。直接上脚本了,clang需要配置的就是cc、ld、cxx这3个在config的默认脚本里是用cross-prefix做前缀,需要修改名字。
这是由于,在/usr/ndk/android-ndk-r20b/toolchains/llvm/prebuilt/linux-x86_64/bin
目录里起名相当混乱

-rwxr-xr-x  1 jack jack      187 10月 17 15:43 aarch64-linux-android21-clang*
-rwxr-xr-x  1 jack jack      191 10月 17 15:43 aarch64-linux-android21-clang++*
...
-rwxr-xr-x  1 jack jack   817728 10月 17 15:34 arm-linux-androideabi-addr2line*
-rwxr-xr-x  1 jack jack   845832 10月 17 15:34 arm-linux-androideabi-ar*
-rwxr-xr-x  1 jack jack  1436624 10月 17 15:34 arm-linux-androideabi-as*
...
-rwxr-xr-x  1 jack jack      190 10月 17 15:43 armv7a-linux-androideabi16-clang*
-rwxr-xr-x  1 jack jack      194 10月 17 15:43 armv7a-linux-androideabi16-clang++*
...
-rwxr-xr-x  1 jack jack      199 10月 17 15:43 i686-linux-android16-clang*
-rwxr-xr-x  1 jack jack      203 10月 17 15:43 i686-linux-android16-clang++*

clang的名字是用PLATFORM+api+clang,负责clang和clang++的脚本名
但是cross-prefix又是$ARCH-linux-androideabi,负责剩下的通用编译工具名
都要对应好,都不能出错。

--ld=$TOOLCHAIN/$TARGET$API-clang 

这行没有错。

最后记得make install

#!/bin/bash

export NDK=/usr/ndk/android-ndk-r20b
export API=21
# arm aarch64 i686 x86_64
export ARCH=arm
# armv7a aarch64 i686 x86_64
export PLATFORM=armv7a
export TARGET=$PLATFORM-linux-androideabi
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
#正确的sysroot
export SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
export CPU=$PLATFORM
export PREFIX=./android/armeabi-v7a2
export CFLAG="-D__ANDROID_API__=$API -Os -fPIC -DANDROID "

./configure \
--prefix=$PREFIX \
--cc=$TOOLCHAIN/$TARGET$API-clang \
--ld=$TOOLCHAIN/$TARGET$API-clang \
--cxx=$TOOLCHAIN/$TARGET$API-clang++ \
--target-os=android  \
--arch=$ARCH \
--cpu=$PLATFORM \
--cross-prefix=$TOOLCHAIN/$ARCH-linux-androideabi- \
--disable-asm \
--enable-cross-compile \
--enable-shared \
--disable-doc \
--enable-runtime-cpudetect \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-decoders \
--disable-encoders \
--disable-devices \
--enable-gpl --enable-nonfree --enable-version3 --disable-iconv \
--enable-jni \
--enable-mediacodec \
--disable-decoders --enable-decoder=vp9 --enable-decoder=h264 --enable-decoder=mpeg4 --enable-decoder=aac \
--disable-encoders --enable-encoder=vp9_vaapi --enable-encoder=h264_nvenc --enable-encoder=h264_v4l2m2m --enable-encoder=hevc_nvenc \
--disable-demuxers --enable-demuxer=rtsp --enable-demuxer=rtp --enable-demuxer=flv --enable-demuxer=h264 \
--disable-muxers --enable-muxer=rtsp --enable-muxer=rtp --enable-muxer=flv --enable-muxer=h264 \
--disable-parsers --enable-parser=mpeg4video --enable-parser=aac --enable-parser=h264 --enable-parser=vp9 \
--disable-protocols --enable-protocol=rtmp --enable-protocol=rtp --enable-protocol=tcp --enable-protocol=udp \
--disable-bsfs \
--disable-indevs \
--disable-outdevs \
--disable-filters \
--disable-postproc \
--sysroot=$SYSROOT \
--extra-cflags="$CFLAG" \
--extra-ldflags=""
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342