使用Android Studio開發FFmpeg的正確姿勢
阿新 • • 發佈:2018-11-13
原文地址:https://www.jianshu.com/p/0a7f3175c1b9
2018-04-21: 更新至 ffmpeg-4.0
使用AndroidStudio 開發 FFmpeg
Keywords: gradle, cmake
關鍵步驟,編譯FFmpeg,Android Studio 整合。abi support:
armeabi
armeabi-v7a
arm64-v8a
x86
x86_64
ndk version android-ndk-r14bexport NDK_HOME=/opt/android/android-ndk-r14b
export NDK_HOST_PLATFORM=linux-x86_64
第一步,編譯ffmpeg
首先下載並解壓
wget https://ffmpeg.org/releases/ffmpeg-4.0.tar.bz2
tar xvf ffmpeg-4.0.tar.bz2
然後編寫編譯指令碼
#!/bin/sh PREFIX=android-build COMMON_OPTIONS="\ --prefix=android/ \ --target-os=android \ --disable-static \ --enable-shared \ --enable-small \ --disable-programs \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --disable-doc \ --disable-symver \ --disable-asm \ " function build_android { ./configure \ --libdir=${PREFIX}/libs/armeabi-v7a \ --incdir=${PREFIX}/includes/armeabi-v7a \ --pkgconfigdir=${PREFIX}/pkgconfig/armeabi-v7a \ --arch=arm \ --cpu=armv7-a \ --cross-prefix="${NDK_HOME}/toolchains/arm-linux-androideabi-4.9/prebuilt/${NDK_HOST_PLATFORM}/bin/arm-linux-androideabi-" \ --sysroot="${NDK_HOME}/platforms/android-19/arch-arm/" \ --extra-cflags="-march=armv7-a -mfloat-abi=softfp -mfpu=neon" \ --extra-ldexeflags=-pie \ ${COMMON_OPTIONS} make clean make -j8 && make install ./configure \ --libdir=${PREFIX}/libs/arm64-v8a \ --incdir=${PREFIX}/includes/arm64-v8a \ --pkgconfigdir=${PREFIX}/pkgconfig/arm64-v8a \ --arch=aarch64 \ --cpu=armv8-a \ --cross-prefix="${NDK_HOME}/toolchains/aarch64-linux-android-4.9/prebuilt/${NDK_HOST_PLATFORM}/bin/aarch64-linux-android-" \ --sysroot="${NDK_HOME}/platforms/android-21/arch-arm64/" \ --extra-ldexeflags=-pie \ ${COMMON_OPTIONS} make clean make -j8 && make install ./configure \ --libdir=${PREFIX}/libs/x86 \ --incdir=${PREFIX}/includes/x86 \ --pkgconfigdir=${PREFIX}/pkgconfig/x86 \ --arch=x86 \ --cpu=i686 \ --cross-prefix="${NDK_HOME}/toolchains/x86-4.9/prebuilt/${NDK_HOST_PLATFORM}/bin/i686-linux-android-" \ --sysroot="${NDK_HOME}/platforms/android-19/arch-x86/" \ --extra-ldexeflags=-pie \ ${COMMON_OPTIONS} make clean make -j8 && make install ./configure \ --libdir=${PREFIX}/libs/x86_64 \ --incdir=${PREFIX}/includes/x86_64 \ --pkgconfigdir=${PREFIX}/pkgconfig/x86_64 \ --arch=x86_64 \ --cpu=x86_64 \ --cross-prefix="${NDK_HOME}/toolchains/x86_64-4.9/prebuilt/${NDK_HOST_PLATFORM}/bin/x86_64-linux-android-" \ --sysroot="${NDK_HOME}/platforms/android-21/arch-x86_64/" \ --extra-ldexeflags=-pie \ ${COMMON_OPTIONS} make clean make -j8 && make install }; build_android
此指令碼實現了armeabi-v7a
,arm64-v8a
,x86
,x86_64
4個平臺的編譯。
- 需要新增系統環境變數
$NDK_PATH
--target-os=android
指定android
平臺。make install-libs
表示只安裝so
檔案
編譯完成結果:
ffmpeg
第二步,專案整合
- 新建專案,增加
C++
支援。手動建立jniLibs
資料夾 - 然後將上一步生成的所有檔案複製到
jniLibs
資料夾下面
最終目錄結構:
project
然後修改CMakeLists.txt
so
。
cmake_minimum_required(VERSION 3.4.1)
find_library(log-lib log)
add_library(native-lib
SHARED
src/main/cpp/native-lib.cpp )
set(JNI_LIBS_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs)
add_library(avutil
SHARED
IMPORTED )
set_target_properties(avutil
PROPERTIES IMPORTED_LOCATION
${JNI_LIBS_DIR}/${ANDROID_ABI}/libavutil.so )
add_library(swresample
SHARED
IMPORTED )
set_target_properties(swresample
PROPERTIES IMPORTED_LOCATION
${JNI_LIBS_DIR}/${ANDROID_ABI}/libswresample.so )
add_library(swscale
SHARED
IMPORTED )
set_target_properties(swscale
PROPERTIES IMPORTED_LOCATION
${JNI_LIBS_DIR}/${ANDROID_ABI}/libswscale.so )
add_library(avcodec
SHARED
IMPORTED )
set_target_properties(avcodec
PROPERTIES IMPORTED_LOCATION
${JNI_LIBS_DIR}/${ANDROID_ABI}/libavcodec.so )
add_library(avformat
SHARED
IMPORTED )
set_target_properties(avformat
PROPERTIES IMPORTED_LOCATION
${JNI_LIBS_DIR}/${ANDROID_ABI}/libavformat.so )
add_library(avfilter
SHARED
IMPORTED )
set_target_properties(avfilter
PROPERTIES IMPORTED_LOCATION
${JNI_LIBS_DIR}/${ANDROID_ABI}/libavfilter.so )
add_library(avdevice
SHARED
IMPORTED )
set_target_properties(avdevice
PROPERTIES IMPORTED_LOCATION
${JNI_LIBS_DIR}/${ANDROID_ABI}/libavdevice.so )
include_directories(${JNI_LIBS_DIR}/includes)
target_link_libraries(native-lib
avutil swresample swscale avcodec avformat avfilter avdevice
${log-lib} )
簡要說明:
${ANDROID_ABI}
表示目標ABI,在官方文件中有說明:https://developer.android.com/ndk/guides/cmake.html
最後再放出效果圖:
FFPlayerDemo
示例程式碼:https://github.com/coopsrc/FFPlayerDemo
作者:Coopsrc
連結:https://www.jianshu.com/p/0a7f3175c1b9
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。
個人補充說明:
加添標頭檔案的時候,要注意一下,不然會報undefined reference to `avcodec_configuration()'的錯誤。
因為ffmpeg是用C寫的,所以在引用它的標頭檔案的時候,需要用extern "c"包起來。
下面是具體的例子:
#include <jni.h>
#include <string>
#ifdef __cplusplus
extern "C" {
#endif
#include "libavcodec/avcodec.h"
#ifdef __cplusplus
}
#endif
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_turner_iplayer_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = avcodec_configuration();//"Hello from C++";
//std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}