我为所有Android架构构建了ffmpeg库。但是有些细节令我困惑。首先让我逐步解释我是如何构建的。
libx264
https://www.videolan.org/developers/x264.html build_all.sh
脚本(在x264文件夹中),为(几乎)所有Android平台创建库。然后我在x264文件夹中获得了android
文件夹。例如x264文件夹中的android/arm
android/arm64
android/x86
android/x86_64
。ffmpeg3.3.4
ffmpeg3.3.4
文件夹副本。用android架构名称命名它们。
与ffmpeg3.3.4-arm64
ffmpeg3.3.4-arm
ffmpeg3.3.4-x86
ffmpeg3.3.4-x86_64
'named'.sh files
中的每一个移动到命名的ffmpeg文件夹。
E.g 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文件夹相同的层次结构中
in(C:\Users\MyName\AppData\Local\Android\sdk\ndk-bundle
)build_android_x86.sh
,build_android_x86_64.sh
..脚本中的每一个。然后我在ffmpeg文件夹中获得了android
个文件夹。 (创建的android
个文件夹有库文件夹)
例如ffmpeg3.3.4-x86/android/x86/(bin,inlude,lib,share)
为所有已创建的Android.mk
文件夹创建了android
个文件,并将其中每个文件夹移动到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
arm64
arm7
(myproject/app/jni/x86
,myproject/app/jni/x86_64
)。
转到ndk路径逐个打开名为ffmpeg的文件夹,并将ffmpeg.c
ffmpeg_filter.c
ffmpeg_opt.c
cmdutils.c
个文件从ffmpeg文件夹复制到" arm命名"文件夹。例如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
创建videoEdit.c而不是运行ndk-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;
}
FFmpeg在Android上运行的命令,在电子邮件上运行速度非常快,但在实际设备上运行速度非常慢。
令我困惑的另一件事是输出./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
编辑在ubuntu上执行的所有这些步骤都会将所有文件夹移动到窗口。所以不要混淆路径。
我要问的所有这些步骤是,我的步骤有什么不对。我应该遵循其他任何方式吗?为什么ffmpeg在真实设备上运行速度较慢。我想知道一件事,如何retrica,snapchat,instagram录制视频作为镜像翻转?它们是否在录制后翻转(如果它们是如何在一秒钟内完成此操作)或者是否在运行时录制视频?我觉得构建ffmpeg for android有点乱,做错事很容易。如果你看看我的步骤,问题并给我一个建议,我将不胜感激。
答案 0 :(得分:3)
ARCH x86 (generic)
这肯定是错的,应该列出具体的架构。
我认为https://github.com/IljaKosynkin/FFmpeg-Development-Kit会对您有所帮助,我能够在第一次尝试时正确构建所有体系结构。您正在使用命令行ffmpeg,因此您需要启用该程序。