android - ライブラリ - ffmpeg アプリ



All Androidアーキテクチャ用のFFmpegを正しく構築する (1)

ARCH                      x86 (generic)

それは間違いなく間違っている、それは特定のアーキテクチャを一覧表示する必要があります。

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

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

  • https://www.videolan.org/developers/x264.htmlから最新バージョンのlibx264をダウンロードしましたhttps://www.videolan.org/developers/x264.html
  • (ほぼ)すべてのAndroidプラットフォーム用のbuild_all.sh作成するためのbuild_all.shスクリプト(x264フォルダー内)を作成して実行します。 それから私はx264フォルダ内のandroidフォルダを手に入れました。 例:x264フォルダのandroid/arm android/arm64 android/x86 android/x86_64
  • https://ffmpeg.org/download.htmlからffmpeg3.3.4をダウンロードしffmpeg3.3.4https://ffmpeg.org/download.html
  • 私はffmpeg3.3.4フォルダを4部作成しました。 アンドロイドアーキテクチャの名前でそれらに名前を付けました。 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_PATHC:\Users\MyName\AppData\Local\Android\sdk\ndk-bundle )に移動しました。
  • C:\Users\MyName\AppData\Local\Android\sdk\ndk-bundle )に、ffmpegフォルダーと同じ階層レベルにx264フォルダーを置きます。
  • build_android_x86.shbuild_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フォルダ( myproject/app/jni/x86myproject/app/jni/x86_64 )に "arm named"フォルダ、例えばx86 x86_4 arm64 arm7を作成します。

  • ndkパスを開き、ffmpegフォルダーを1つずつ開いて、ffmpegフォルダーからffmpeg_filter.c ffmpeg_opt.c cmdutils.cファイルを "arm named"フォルダーにコピーします。 例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 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;
}

FFmpegアンドロイド上で実行され、Emaulator上では非常に速く動作しますが、実際のデバイス上では非常に遅く動作するコマンド

私の頭を混乱させるもう一つのことは、。/ ./configureコマンドの出力です。 私は(例) ffmpeg-3.3.4-arm64-v8aフォルダをffmpeg-3.3.4-arm64-v8a 、ターミナルで./configureコマンドを実行します。 出力はARCH x86 (generic)と言います。 すべてのプラットフォームでの出力は同じARCH x86 (generic)です。

ffmpeg-3.3.4-arm64-v8aフォルダーに./configureコマンドを出力

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

ubuntuで行われたこれらすべての手順を編集してから、すべてのフォルダをウィンドウに移動します。 だから道を混同しないでください。

私が尋ねたいと思うこれらすべてのステップで、私のステップに何か問題があるのでしょうか。 私は他の方法に従うべきかどうか? なぜffmpegが実際のデバイスでは遅くなっているのですか。 私はひどく不思議に思っています、どのようにretrica、snapchat、instagramはミラー反転としてビデオを録画しますか? 録画した後に反転していますか(1秒間にこれをどのように実行しているか)、または実行時に反転してビデオを録画していますか。 私は、アンドロイド向けのffmpegの構築は少し面倒で、間違ったものを作るのはとても簡単だと思います。 あなたが私のステップ、質問を見て、私にアドバイスを与えてくれれば、私は大いに感謝されるでしょう。





java-native-interface