为所有Android架构正确构建FFmpeg

为所有Android架构正确构建FFmpeg,android,ffmpeg,android-ndk,java-native-interface,Android,Ffmpeg,Android Ndk,Java Native Interface,我为所有android架构构建了ffmpeg库。但有些细节让我困惑。首先,让我一步一步地解释我是如何构建的 我从下载了最新版本的libx264 创建并运行build_all.shscript(在x264文件夹中)为(几乎)所有android平台创建lib。然后我得到了x264文件夹中的android文件夹。e、 gandroid/armandroid/arm64android/x86android/x86\u 64在x264文件夹中 我从下载ffmpeg3.3.4 我创建了4份ffmpeg3

我为所有android架构构建了ffmpeg库。但有些细节让我困惑。首先,让我一步一步地解释我是如何构建的

  • 我从下载了最新版本的
    libx264
  • 创建并运行
    build_all.sh
    script(在x264文件夹中)为(几乎)所有android平台创建lib。然后我得到了x264文件夹中的
    android
    文件夹。e、 g
    android/arm
    android/arm64
    android/x86
    android/x86\u 64
    在x264文件夹中
  • 我从下载
    ffmpeg3.3.4
  • 我创建了4份
    ffmpeg3.3.4
    文件夹。用安卓架构的名字给它们命名。 如
    ffmpeg3.3.4-arm64
    ffmpeg3.3.4-arm
    ffmpeg3.3.4-x86
    ffmpeg3.3.4-x86
  • 为android的每个平台创建了build(架构名称).sh。然后根据体系结构名称将每个
    'named'.sh文件
    移动到命名的ffmpeg文件夹中。 例如
    build\u android\u x86.sh
    =>
    ffmpeg3.3.4-x86
build\u android\u arm64.sh
示例

#!/bin/bash
#Change NDK to your Android NDK location
NDK=$HOME/Android/Sdk/ndk-bundle
PLATFORM=$NDK/platforms/android-21/arch-arm64/
PREBUILT=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64

GENERAL="\
--enable-small \
--enable-cross-compile \
--extra-libs="-lgcc" \
--arch=aarch64 \
--cc=$PREBUILT/bin/aarch64-linux-android-gcc \
--cross-prefix=$PREBUILT/bin/aarch64-linux-android- \
--nm=$PREBUILT/bin/aarch64-linux-android-nm \
--extra-cflags="-I../x264/android/arm64/include" \
--extra-ldflags="-L../x264/android/arm64/lib" "

MODULES="\
--enable-gpl \
--enable-libx264"



function build_arm64
{
  ./configure \
  --logfile=conflog.txt \
  --target-os=linux \
  --prefix=./android/arm64-v8a \
  ${GENERAL} \
  --sysroot=$PLATFORM \
  --extra-cflags="" \
  --extra-ldflags="-lx264 -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog" \
  --enable-shared \
  --disable-static \
  --disable-doc \
  --enable-zlib \
  ${MODULES}

  make clean
  make
  make install
}

build_arm64


echo Android ARM64 builds finished
  • 将所有
    ffmpeg3.3.4-arm64
    ffmpeg3.3.4-arm
    ffmpeg3.3.4-x86
    ffmpeg3.3.4-x86\u 64
    文件夹移动到
    NDK\u路径
    C:\Users\MyName\AppData\Local\Android\sdk\NDK bundle
  • x264
    文件夹与ffmpeg文件夹放在同一层次上 在(
    C:\Users\MyName\AppData\Local\Android\sdk\ndk bundle
  • 运行每个
    build\u android\u x86.sh
    build\u android\u x86\u 64.sh
    。。在各自的ffmpeg文件夹中逐个编写脚本。然后我得到了ffmpeg文件夹中的
    android
    文件夹。(创建的
    android
    文件夹具有库文件夹) e、 g
    ffmpeg3.3.4-x86/android/x86/(bin、inlude、lib、share)
  • 为所有创建的
    Android
    文件夹创建了
    Android.mk
    文件,并将每个文件夹移动到Android/armName文件夹。e、 g
    Android.mk
    =>
    ffmpeg3.3.4-x86/Android/x86/

    LOCAL_PATH:= $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= libavcodec
    LOCAL_SRC_FILES:= lib/libavcodec-57.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= libavformat
    LOCAL_SRC_FILES:= lib/libavformat-57.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= libswscale
    LOCAL_SRC_FILES:= lib/libswscale-4.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= libavutil
    LOCAL_SRC_FILES:= lib/libavutil-55.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= libavfilter
    LOCAL_SRC_FILES:= lib/libavfilter-6.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= libswresample
    LOCAL_SRC_FILES:= lib/libswresample-2.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := postproc
    LOCAL_SRC_FILES := lib/libpostproc-54.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := avdevice
    LOCAL_SRC_FILES := lib/libavdevice-57.so
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
    include $(PREBUILT_SHARED_LIBRARY)
    
  • 在我的项目的jni文件夹中创建“arm命名”文件夹,例如
    x86
    x86\u 4
    arm64
    arm7
    myproject/app/jni/x86
    myproject/app/jni/x86\u 64

  • 转到ndk路径逐个打开命名的ffmpeg文件夹,并将文件从ffmpeg文件夹复制到“arm命名”文件夹。e、 g
    ffmpeg.c
    =>
    myproject/app/jni/x86

  • 在我的项目中创建了Android.mk文件

    LOCAL_PATH := $(call my-dir)
    #$(warning $(LOCAL_PATH))
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := videoEdit
    LOCAL_LDLIBS := -llog -ljnigraphics -lz -landroid
    LOCAL_CFLAGS := -Wdeprecated-declarations
    ANDROID_LIB := -landroid
    
    $(info $(TARGET_ARCH_ABI))
    
    ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
        LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg-3.3.4-armeabi
        LOCAL_SRC_FILES :=  videoEdit.c arm7/ffmpeg.c arm7/ffmpeg_filter.c arm7/ffmpeg_opt.c arm7/cmdutils.c
        LOCAL_CFLAGS += -lx264 -Wl,--no-merge-exidx-entries
    else
    
        ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
                LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg-3.3.4-arm64-v8a
                LOCAL_SRC_FILES :=  videoEdit.c arm64/ffmpeg.c arm64/ffmpeg_filter.c arm64/ffmpeg_opt.c arm64/cmdutils.c
                LOCAL_CFLAGS += -funwind-tables -Wl,--no-merge-exidx-entries
        else
    
            ifeq ($(TARGET_ARCH_ABI),x86_64)
                   LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg3.3.4-x86_64
                   LOCAL_SRC_FILES :=  videoEdit.c x86_64/ffmpeg.c x86_64/ffmpeg_filter.c x86_64/ffmpeg_opt.c x86_64/cmdutils.c
            else
                    LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg3.3.4-x86
                    LOCAL_SRC_FILES :=  videoEdit.c x86/ffmpeg.c x86/ffmpeg_filter.c x86/ffmpeg_opt.c x86/cmdutils.c
            endif
    
        endif
    
    endif
    
    LOCAL_SHARED_LIBRARIES := libavformat libavcodec libswscale libavutil libswresample libavfilter libavdevice libpostproc
    
    include $(BUILD_SHARED_LIBRARY)
    
    ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
    
        $(call import-module,ffmpeg-3.3.4-armeabi/android/armeabi-v7a)
    
    else
    
        ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
                $(call import-module,ffmpeg-3.3.4-arm64-v8a/android/arm64-v8a)
        else
    
            ifeq ($(TARGET_ARCH_ABI),x86_64)
                   $(call import-module,ffmpeg3.3.4-x86_64/android/x86_64)
            else
                $(call import-module,ffmpeg3.3.4-x86/android/i686-diasm)
            endif
    
        endif
    
    endif
    
    APP_ABI := armeabi-v7a, arm64-v8a, x86_64, x86
    APP_PLATFORM := android-14
    
  • 在我的项目中创建了Application.mk文件

    LOCAL_PATH := $(call my-dir)
    #$(warning $(LOCAL_PATH))
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := videoEdit
    LOCAL_LDLIBS := -llog -ljnigraphics -lz -landroid
    LOCAL_CFLAGS := -Wdeprecated-declarations
    ANDROID_LIB := -landroid
    
    $(info $(TARGET_ARCH_ABI))
    
    ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
        LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg-3.3.4-armeabi
        LOCAL_SRC_FILES :=  videoEdit.c arm7/ffmpeg.c arm7/ffmpeg_filter.c arm7/ffmpeg_opt.c arm7/cmdutils.c
        LOCAL_CFLAGS += -lx264 -Wl,--no-merge-exidx-entries
    else
    
        ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
                LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg-3.3.4-arm64-v8a
                LOCAL_SRC_FILES :=  videoEdit.c arm64/ffmpeg.c arm64/ffmpeg_filter.c arm64/ffmpeg_opt.c arm64/cmdutils.c
                LOCAL_CFLAGS += -funwind-tables -Wl,--no-merge-exidx-entries
        else
    
            ifeq ($(TARGET_ARCH_ABI),x86_64)
                   LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg3.3.4-x86_64
                   LOCAL_SRC_FILES :=  videoEdit.c x86_64/ffmpeg.c x86_64/ffmpeg_filter.c x86_64/ffmpeg_opt.c x86_64/cmdutils.c
            else
                    LOCAL_C_INCLUDES:=/Users/MyName/AppData/Local/Android/sdk/ndk-bundle/sources/ffmpeg3.3.4-x86
                    LOCAL_SRC_FILES :=  videoEdit.c x86/ffmpeg.c x86/ffmpeg_filter.c x86/ffmpeg_opt.c x86/cmdutils.c
            endif
    
        endif
    
    endif
    
    LOCAL_SHARED_LIBRARIES := libavformat libavcodec libswscale libavutil libswresample libavfilter libavdevice libpostproc
    
    include $(BUILD_SHARED_LIBRARY)
    
    ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
    
        $(call import-module,ffmpeg-3.3.4-armeabi/android/armeabi-v7a)
    
    else
    
        ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
                $(call import-module,ffmpeg-3.3.4-arm64-v8a/android/arm64-v8a)
        else
    
            ifeq ($(TARGET_ARCH_ABI),x86_64)
                   $(call import-module,ffmpeg3.3.4-x86_64/android/x86_64)
            else
                $(call import-module,ffmpeg3.3.4-x86/android/i686-diasm)
            endif
    
        endif
    
    endif
    
    APP_ABI := armeabi-v7a, arm64-v8a, x86_64, x86
    APP_PLATFORM := android-14
    
  • 创建videoEdit.c,然后运行
    ndk build
    build命令

无错误构建。我可以运行ffmpeg命令,但我认为这需要花费太多的时间。例如,当我尝试运行
hflip
时,它会以15秒的时间翻转视频

代码示例:

JNIEXPORT jint JNICALL Java_com_name_app_library_VideoEditer_natives_VideoEditer_flipHorizontally
(JNIEnv *env, jclass someclass, jstring inputFile, jstring outFile) {

    int numberOfArgs = 14;

    char** arguments = calloc(numberOfArgs, sizeof(char*));
    const char *in, *out;

    in = (*env)->GetStringUTFChars(env, inputFile, 0);
    out = (*env)->GetStringUTFChars(env, outFile, 0);

    arguments[0] = "ffmpeg";
    arguments[1] = "-i";
    arguments[2] = in;
    arguments[3] = "-c:v";
    arguments[4] = "libx264";
    arguments[5] = "-preset";
    arguments[6] = "ultrafast";
    arguments[7] = "-threads";
    arguments[8] = "5";
    arguments[9] = "-c:a";
    arguments[10] = "copy";
    arguments[11] = "-vf";
    arguments[12] = "hflip";
    arguments[13] = out;

    int i;
    for (i = 0; i < numberOfArgs; i++) {
        log_message(arguments[i]);
    }
    log_message("Printed all");

    main(numberOfArgs, arguments);
    free(arguments);
    (*env)->ReleaseStringUTFChars(env, inputFile, in);
    (*env)->ReleaseStringUTFChars(env, outFile, out);

    return 0;
}
编辑在ubuntu上执行的所有步骤,然后将所有文件夹移动到windows。所以不要混淆路径

有了这些步骤,我想问的是,我的步骤有什么问题吗。我该不该走别的路?ffmpeg在真实设备上运行较慢的原因。我很想知道一件事,那就是retrica、snapchat、instagram如何以镜像翻转的方式录制视频?他们是在录制后翻页(如果是的话,他们是如何在一秒钟内完成的),还是在运行时以翻页的方式录制视频?我猜为android构建ffmpeg有点混乱,很容易出错。如果你看看我的步骤,问题,给我一个建议,我将不胜感激

ARCH                      x86 (generic)
这绝对是错误的,它应该列出具体的体系结构


我想这会对您有所帮助,我第一次使用它就能够正确地构建所有体系结构。您正在使用命令行ffmpeg,因此需要启用该程序。

我将查看构建文件的拱门。另外,您是否缺少
$(调用导入模块,android/cpufeatures)
?IIRC,这是打开霓虹灯优化代码所必需的。请查看哪个文件的版本,抱歉,无法理解。您的意思是libx264的生成文件还是ffmpeg文件的生成文件?确实缺少。我将添加
$(调用导入模块,android/cpufeatures)
让我们看看它的效果。@JamesPoag添加
cpufeatures
(编译无误)后,
hflip
视频的性能没有变化。@fthopkins很抱歉问了一个愚蠢的问题。为什么要使用libx264并在此目录中运行所有脚本?编译FFMPEG需要libx264吗?这个答案是解决我问题的最佳方法。谢谢。@fthopkins请告诉我们您做错了什么,以及如何解决问题。您是否遵循了解决问题的步骤?为了解决问题,您到底更新了哪些内容?