我为所有 android 架构构建了 ffmpeg 库。但是有些细节让我很困惑。首先让我一步一步解释我是如何构建的。
libx264
从https://www.videolan.org/developers/x264.html
build_all.sh
用于为(几乎)所有 android 平台创建库的脚本(在 x264 文件夹中)。然后我得到了android
x264 文件夹中的文件夹。例如 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
'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文件夹中一一对应。然后我得到了android
ffmpeg 文件夹中的文件夹。 (创建 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)
x86
x86_4
arm64
arm7
在我项目的 jni 文件夹中( myproject/app/jni/x86
, myproject/app/jni/x86_64
)。 ffmpeg.c
ffmpeg_filter.c
ffmpeg_opt.c
cmdutils.c
ffmpeg 文件夹中的文件到“arm named”文件夹。例如 ffmpeg.c
=> myproject/app/jni/x86
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
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;
}
在 android 上运行的 FFmpeg 命令,在 emulator 上运行速度非常快,但在真实设备上运行速度非常慢。
另一个让我困惑的事情是
./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 上进行的所有这些步骤然后将所有文件夹移动到 Windows。所以不要混淆路径。
对于所有这些步骤,我想问的是,我的步骤有什么问题吗?我应该遵循其他方式吗?为什么 ffmpeg 在真实设备上运行速度较慢。我很想知道一件事,retrica、snapchat、instagram 如何将视频录制为镜像翻转?他们是在录制后翻转(如果他们在一秒钟内如何做到这一点)还是在录制运行时翻转的视频?我想为 android 构建 ffmpeg 有点乱,而且做错事很容易。如果您查看我的步骤,问题并给我建议,我将不胜感激。
最佳答案
ARCH x86 (generic)
那肯定是错的,应该列出具体的架构。
我认为 https://github.com/IljaKosynkin/FFmpeg-Development-Kit会帮助你,我能够在第一次尝试时正确地构建所有架构。您正在使用命令行 ffmpeg,因此您需要启用该程序。
关于android - 正确构建适用于所有 Android 架构的 FFmpeg,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46871831/