Ubuntu下使用as搭建最新ffmpeg3.2.2
编译ffmpeg踩了不少坑,写下来记录一下,以后用。使用到的环境和工具如下:
- Android Studio 2.2.2
- Ubuntu 16.04环境下
- ffmpeg3.2.2
1,下载ffmpeg3.2.2
直接去http://ffmpeg.org/下载,然后解压后进入ffmpeg根目录,修改configure文件,将:
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)'
然后编写一个build.sh脚本,网上很多,我这里一个抄的:
#!/bin/bash NDK=/home/huimingli/Downloads/android-sdk-linux/ndk-bundle SYSROOT=$NDK/platforms/android-24/arch-arm TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 function build_one { ./configure \ --prefix=$PREFIX \ --enable-shared \ --disable-static \ --disable-doc \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --disable-ffserver \ --disable-avdevice \ --disable-doc \ --disable-symver \ --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \ --target-os=linux \ --arch=arm \ --enable-cross-compile \ --sysroot=$SYSROOT \ --extra-cflags="-Os -fpic $ADDI_CFLAGS" \ --extra-ldflags="$ADDI_LDFLAGS" \ $ADDITIONAL_CONFIGURE_FLAG make clean make make install } cpu=arm PREFIX=/home/huimingli/Desktop/f ADDI_CFLAGS="-marm" build_one
前面的一些内容根据自己的机器修改一下即可:然后ctrl+alt+t,弹出terminal,输入sudo ./build.sh,跑起来,一会后在脚本中的PREFIX,你输入的目录中出现include,和lib文件夹。等会用。
2,新建工程
1,在as下file->new->new project,输入工程名FFmpegTest,不要勾选include C++support,然后一路next,最后finish即可。
2,在gradle.properties中添加android.useDeprecatedNdk= true,否则会因为没有ndk支持导致报错。local.properties中配置sdk.dir,ndk.dir
3,在main目录下新建jni文件
4,在app下的build.gradle中的android中添加代码如下:
sourceSets {
main {
jni.srcDirs = [] //防止as重build c/C++文件,非常重要
jniLibs.srcDir 'src/main/libs' //找到so文件
}
}
android中的defaultconfig中添加:
ndk { moduleName "helloworld" ldLibs "log","z","m" abiFilters "armeabi","armeabi-v7a" }
然后新工程建立完毕。然后将前面生成的include中的所有文件,以及lib中所有的so文件复制粘贴到jni目录。然后在jni目录下创建两个文件,Android.mk,和Application.mk.
Android.mk代码如下:
LOCAL_PATH := $(call my-dir) # FFmpeg library include $(CLEAR_VARS) LOCAL_MODULE := avcodec LOCAL_SRC_FILES := libavcodec.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avfilter LOCAL_SRC_FILES := libavfilter.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avformat LOCAL_SRC_FILES := libavformat.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avutil LOCAL_SRC_FILES := libavutil.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := swresample LOCAL_SRC_FILES := libswresample.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := swscale LOCAL_SRC_FILES := libswscale.so include $(PREBUILT_SHARED_LIBRARY) # Program include $(CLEAR_VARS) LOCAL_MODULE := helloworld LOCAL_SRC_FILES := helloworld.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代码如下:
#APP_ABI := all #APP_ABI := armeabi armeabi-v7a x86 APP_ABI :=armeabi-v7a
然后开始修改MainActivity了,编写布局文件。代码如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.android.camera.myapplication.MainActivity"> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/txt" android:scrollbarStyle="insideInset" android:layout_width="match_parent" android:layout_height="match_parent" android:text="Hello World!" /> </ScrollView> </RelativeLayout>
MainActivity代码如下:
public class MainActivity extends Activity { static { System.loadLibrary("helloworld"); System.loadLibrary("avcodec"); System.loadLibrary("avfilter"); System.loadLibrary("avformat"); System.loadLibrary("avutil"); System.loadLibrary("swresample"); System.loadLibrary("swscale"); } public native String avcodecinfo(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ((TextView)findViewById(R.id.txt)).setText(avcodecinfo()); } }
然后就build->make project,构建工程,生成class,接着要生成头文件了,在工程目录下打开terminal,输入javah -classpath /home/huimingli/Downloads/android-sdk-linux/platforms/android-24/android.jar:./app/build/intermediates/classes/debug com.xxx.xxx.MainActivity,这里有个坑,linux环境下中间是:而不是;
把生成的头文件放到jni目录下,再创建helloworld.c文件,代码如下
#include <stdio.h> #include <jni.h> #include "com_android_camera_ffmpegtest_MainActivity" #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavfilter/avfilter.h" #include "libavutil/avutil.h" //Log #ifdef ANDROID #include <jni.h> #include <android/log.h> #define LOGE(format,...) __android_log_print(ANDROID_LOG_ERROR,"(>_<)",format,##__VA_ARGS__) #else #define LOGE(format,...) printf("(>_<) " format "\n",##__VA_ARGS__) #endif JNIEXPORT jstring JNICALL Java_com_android_camera_ffmpegtest_MainActivity_avcodecinfo (JNIEnv *env,jobject obj){ char info[10000] = { 0 }; sprintf(info,"%s\n",avcodec_configuration(),avcodec_license()); return (*env)->NewStringUTF(env,info); }打开terminal,跳转到app/src/main目录下,执行ndk-build,不报错就成功了,会发现多出两个文件夹libs和obj。然后就完成了,run一个。
显示上面的内容说明成功搭建成功了,欢迎进入ffmpeg的世界!另外每次修改完代码都要ndk-build一下很麻烦,可以在app下的build.gradle中添加任务:
task ndkBuild(type: Exec) { commandLine 'ndk-build','-C',file('src/main/jni').absolutePath } tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn ndkBuild }它就会run之前自己跑一个ndk-build了,修改完代码直接run一个。 原文链接:https://www.f2er.com/ubuntu/355186.html