web-dev-qa-db-ja.com

すべてのFFmpegをビルドするAndroidアーキテクチャを正しく構築する

私はすべてのAndroidアーキテクチャ用のffmpegライブラリを構築しました。しかし、いくつかの詳細は私の心を混乱させます。まず、私がどのように構築したかを段階的に説明しましょう。

  • _libx264_の最新バージョンを https://www.videolan.org/developers/x264.html からダウンロードしました
  • (ほぼ)すべてのAndroidプラットフォーム用のライブラリを作成するための_build_all.sh_スクリプト(x264フォルダー内)を作成して実行します。次に、x264フォルダー内にAndroidフォルダーを取得しました。例:_Android/arm_ _Android/arm64_ _Android/x86_ _Android/x86_64_ x264フォルダー内。
  • _ffmpeg3.3.4_を https://ffmpeg.org/download.html からダウンロードします
  • _ffmpeg3.3.4_フォルダーのコピーを4つ作成しました。 Androidアーキテクチャ名。_ffmpeg3.3.4-arm64_ _ffmpeg3.3.4-arm_ _ffmpeg3.3.4-x86_ _ffmpeg3.3.4-x86_64_のように)
  • Androidのプラットフォームごとにbuild_(architecture-name).shを作成しました。 _'named'.sh files_のそれぞれをアーキテクチャ名に従って指定されたffmpegフォルダに移動するよりも。例:_build_Android_x86.sh_ => _ffmpeg3.3.4-x86_

_build_Android_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_64_フォルダーを_NDK_PATH_(_C:\Users\MyName\AppData\Local\Android\sdk\ndk-bundle_)に移動しました
  • _x264_フォルダーをffmpegフォルダーと同じ階層レベルに配置します(_C:\Users\MyName\AppData\Local\Android\sdk\ndk-bundle_)
  • _build_Android_x86.sh_、_build_Android_x86_64.sh_ ..スクリプトをそれぞれ独自のffmpegフォルダーで1つずつ実行します。次に、ffmpegフォルダーにAndroidフォルダーを取得しました。 (作成されたAndroidフォルダーにはライブラリフォルダーがあります)例:ffmpeg3.3.4-x86/Android/x86/(bin,inlude,lib,share)
  • 作成されたすべてのAndroidフォルダーに対して_Android.mk_ファイルを作成し、それぞれをAndroid/armNameフォルダーに移動しました。例:_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フォルダー(_x86_、_x86_4_)に「armnamed」フォルダーを作成します(例:_arm64_ _arm7_ _myproject/app/jni/x86_ _myproject/app/jni/x86_64_)。

  • Ndkパスに移動して名前付きffmpegフォルダーを1つずつ開き、_ffmpeg.c_ _ffmpeg_filter.c_ _ffmpeg_opt.c_ _cmdutils.c_ファイルをffmpegフォルダーから「armnamed」フォルダーにコピーします。例:_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
    _
  • プロジェクトにApplication.mkファイルを作成しました。

    _APP_ABI := armeabi-v7a, arm64-v8a, x86_64, x86
    APP_PLATFORM := Android-14
    _
  • _ndk-build_ビルドコマンドを実行するよりもvideoEdit.cを作成しました。

エラーなしで構築されました。 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;
}
_

Androidで実行されるFFmpegコマンド。emaulatorでは非常に高速に動作しますが、実際のデバイスでは非常に低速です。

また、私の心を混乱させるもう1つのことは、_./configure_コマンドの出力です。 (例)_ffmpeg-3.3.4-arm64-v8a_フォルダーを開き、ターミナルで_./configure_コマンドを実行すると。出力にはArch x86 (generic)と表示されます。すべてのプラットフォームの出力は同じArch x86 (generic)です。

_./configure_フォルダー内の_ffmpeg-3.3.4-arm64-v8a_コマンドの出力

_install prefix            /usr/local
source path               .
C compiler                gcc
C library                 glibc
Arch                      x86 (generic)
big-endian                no
runtime cpu detection     yes
yasm                      yes
MMX enabled               yes
MMXEXT enabled            yes
3DNow! enabled            yes
3DNow! extended enabled   yes
SSE enabled               yes
SSSE3 enabled             yes
AESNI enabled             yes
AVX enabled               yes
XOP enabled               yes
FMA3 enabled              yes
FMA4 enabled              yes
i686 features enabled     yes
CMOV is fast              yes
EBX available             yes
EBP available             yes
debug symbols             yes
strip symbols             yes
optimize for size         no
optimizations             yes
static                    yes
shared                    no
postprocessing support    no
network support           yes
threading support         pthreads
safe bitstream reader     yes
texi2html enabled         no
Perl enabled              yes
pod2man enabled           yes
makeinfo enabled          no
makeinfo supports HTML    no

External libraries:
iconv            xlib
_

[〜#〜] edit [〜#〜]ubuntuで行われたこれらすべての手順は、すべてのフォルダーをウィンドウに移動しました。したがって、パスについて混乱しないでください。

私が聞きたいこれらのすべてのステップで、私のステップに何か問題がありますか?他の方法に従うべきかどうか? ffmpegが実際のデバイスで遅くなる理由。私はひどく1つのことを疑問に思っています、どのようにレトリカ、スナップチャット、ミラーリングされたフリッピングとしてビデオを記録するインスタグラム?彼らは録画後に反転していますか(彼らが1秒でこれをどのように行っているか)、または実行時に反転してビデオを録画していますか? Androidは少し面倒で、間違ったものを作るのはとても簡単だと思います。私の手順や質問を見てアドバイスをいただければ幸いです。

14
fthopkins
Arch                      x86 (generic)

それは間違いなく間違っています、それは特定のアーキテクチャをリストしているはずです。

https://github.com/IljaKosynkin/FFmpeg-Development-Kit が役立つと思います。最初に試してみると、すべてのアーキテクチャを正しく構築できました。コマンドラインffmpegを使用しているため、プログラムを有効にする必要があります。

3
Steve M