Mac環境下Android Studio移植FFmpeg
阿新 • • 發佈:2018-11-22
準備:
1. Android Studio 2. FFmpeg-2.8.4 3. android-ndk-r10e一、ndk編譯ffmpeg
1.下載ffmpeg和ndk
ffmpeg下載地址:http://ffmpeg.org/download.html 我下載的是2.8.4版本 ndk 官網下載,這個我就不說了,自備梯子翻越長城。。我下載的是 android-ndk-r10e2.解壓ffmpeg和ndk
將解壓的ffmpeg資料夾複製到 android-ndk-r10e ->sources 目錄中SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'
修改為:
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
3.配置編譯指令碼
在資料夾ffmpeg-2.8.4中新建指令碼 build_android.sh注意的是前面三個路徑替換成自己的路徑,還有一些不同版本ndk路徑的取名不同比如darwin-x86_64有的是linux-x86_64,自己注意一下路徑名稱#!/bin/bash export NDK=/Users/huxing/Downloads/android-ndk-r10e export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt export PLATFORM=$NDK/platforms/android-21/arch-arm export PREFIX=../simplefflib build_one(){ ./configure --target-os=linux --prefix=$PREFIX \ --enable-cross-compile \ --enable-runtime-cpudetect \ --disable-asm \ --arch=arm \ --cc=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi-gcc \ --cross-prefix=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi- \ --disable-stripping \ --nm=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi-nm \ --sysroot=$PLATFORM \ --enable-gpl --enable-shared --disable-static --enable-small \ --disable-ffprobe --disable-ffplay --disable-ffmpeg --disable-ffserver --disable-debug \ --extra-cflags="-fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm -march=armv7-a" } build_one make make install
4.編譯ffmpeg
使用命令cd到指令碼目錄下,首先 chmod a+x build_android.sh 授權,然後 ./build_android.sh 執行指令碼。 編譯需要花一些時間,編譯完成之後就會在android-ndk-r10e -> source 目錄下多出一個 simplefflib 目錄 (還有8個.so檔案被我刪除了)二、Android Studio 部分
1.新建 Android Studio工程
新建AS工程,在main目錄下新建一個jni目錄,在gradle.properties配置中新增 android.useDeprecatedNdk = true,在Project Structure中配置ndk location,指向你下載ndk的路徑再將編譯的FFmpeg檔案複製到jni目錄中。
2.配置build.gradle
取消自動編譯,新增 : sourceSets.main.jni.srcDirs = []
新增ndk配置:
ndk {
moduleName "helloffmpeg"
abiFilter "armeabi"
ldLibs "log", "z", "m", "jnigraphics", "android"
}
全部配置為如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.0"
sourceSets.main.jni.srcDirs = []
defaultConfig {
applicationId "hxing.com.myffmpeg"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName "helloffmpeg"
abiFilter "armeabi"
ldLibs "log", "z", "m", "jnigraphics", "android"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
3.生成標頭檔案
在MainActivity.class中新增Native方法和呼叫庫檔案,如下:public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("helloffmpeg");
System.loadLibrary("avutil-54");
System.loadLibrary("avcodec-56");
System.loadLibrary("avformat-56");
System.loadLibrary("avdevice-56");
System.loadLibrary("swresample-1");
System.loadLibrary("swscale-3");
System.loadLibrary("postproc-53");
System.loadLibrary("avfilter-5");
}
public native String getffmpegFromJNI();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.text);
textView.setText(getffmpegFromJNI());
}
}
開啟as的Terminal視窗,預設路徑是當前專案根路徑,輸入以下命令:
cd app/src/main/java
javah -d ../jni hxing.com.myffmpeg.MainActivity
進入java目錄下 使用javah命令在jni目錄下生成標頭檔案,然後再在jni目錄下建立對應的c檔案,c檔案程式碼如下:
//
// Created by 胡醒 on 15/12/31.
//
#include <jni.h>
#include "libavcodec/avcodec.h"
JNIEXPORT jstring JNICALL Java_hxing_com_myffmpeg_MainActivity_getffmpegFromJNI
(JNIEnv * env, jobject thiz){
char info[10000] = { 0 };
sprintf(info, "%s\n", avcodec_configuration());
return (*env)->NewStringUTF(env, info);
}
4.在jni目錄下建立Android.mk檔案
LOCAL_PATH := $(call my-dir)
# FFmpeg library
include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := lib/libavcodec-56.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avdevice
LOCAL_SRC_FILES := lib/libavdevice-56.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avfilter
LOCAL_SRC_FILES := lib/libavfilter-5.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avformat
LOCAL_SRC_FILES := lib/libavformat-56.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := lib/libavutil-54.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := postproc
LOCAL_SRC_FILES := lib/libpostproc-53.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swresample
LOCAL_SRC_FILES := lib/libswresample-1.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES := lib/libswscale-3.so
include $(PREBUILT_SHARED_LIBRARY)
# Program
include $(CLEAR_VARS)
LOCAL_MODULE := helloffmpeg
LOCAL_SRC_FILES := hxing_com_myffmpeg_MainActivity.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_LDLIBS := -llog -lz
LOCAL_SHARED_LIBRARIES := avcodec avdevice avfilter avformat avutil postproc swresample swscale
include $(BUILD_SHARED_LIBRARY)
還可以在當前目錄下建立Application.mk,這個檔案用來指定編譯的平臺,我這裡只指定armeabi
APP_ABI := armeabi
5.編譯ffmpeg.so檔案
進入Terminal視窗,輸入命令 “ cd ../jni” 返回到jni目錄中,在輸入命令:/Users/huxing/Downloads/android-ndk-r10e/ndk-build NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/Users/huxing/Documents/myFFmpeg2/app/src/main/jni/Android.mk APP_PLATFORM=android-21 NDK_OUT=/Users/huxing/Documents/myFFmpeg2/app/build/intermediates/ndk/debug/obj NDK_LIBS_OUT=/Users/huxing/Documents/myFFmpeg2/app/build/intermediates/ndk/debug/lib APP_ABI=armeabi
/Users/huxing/Downloads/android-ndk-r10e/ndk-build :你安裝的ndk目錄中的ndk-build命令 APP_BUILD_SCRIPT :工程中jni目錄下的android.mk的路徑
NDK_OUT : 輸出路徑
NDK_LIBS_OUT :庫檔案輸出路徑
APP_ABI : 輸出平臺
改成自己工程對應的目錄