Android:WIN10+MinGW+NDK编译FFmpeg
来源:互联网 发布:环信 服务端开发 java 编辑:程序博客网 时间:2024/05/16 13:41
前言:
Android音视频开发的话,FFmpeg总是必须的,出于学习目的,花时间起了个开头。
FFmpeg源码是很多的c文件,首先要借助工具编译出so库,仅有这个Android是无法调用的,必须再用JNI写一层Android能用的接口。网上资料非常多,但是看了几天下来,编译平台和工具版本的差异总是存在,编译过程中也有各种各样的问题。这里给出自己的编译过程,希望给刚好需要的同学。
到写文章为止,所有源码和工具都是用的最新版。
一.MinGW编译出so库
http://ffmpeg.org/下载源码,解压到一个文件夹里
https://sourceforge.net/projects/mingw/files/下载MinGW,把相应的选项都勾上,环境变量配置好。
找到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)'
在ffmpeg下新建一个build_android.sh,将以下代码复制进去
1)前三行按实际情况替换
2)这里我用notepad++编辑将文件格式改为Unix格式,否则会有一些换行符等Windows与Linux平台差异问题编译出问题
#!/bin/shNDK=D:/Program/android-ndk-r14bSYSROOT=$NDK/platforms/Android-21/arch-armTOOLCHAIN=$NDK/toolchains/arm-Linux-androideabi-4.9/prebuilt/windows-x86_64function build_one{./configure \--prefix=$PREFIX \--enable-shared \--enable-gpl \--disable-static \--disable-doc \--disable-ffmpeg \--disable-ffplay \--disable-ffprobe \--disable-ffserver \--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_FLAGmake cleanmakemake install}CPU=armPREFIX=$(pwd)/libs/$CPUADDI_CFLAGS="-marm"build_one
之后打开下载好的MinGW的 MinGW\msys\1.0\msys.bat,执行以下命令
耐心等待后,ffmpeg下多出一个libs文件夹,里面就是我们想要的东西了
二.NDK编译JNI
还是在ffmpeg目录下,新建一个jni目录,里面是这些东西
其中Android.mk
APP_ALLOW_MISSING_DEPS=trueLOCAL_PATH := $(call my-dir)# FFmpeg libraryinclude $(CLEAR_VARS)LOCAL_MODULE := avcodecLOCAL_SRC_FILES := libavcodec-57.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := avfilterLOCAL_SRC_FILES := libavfilter-6.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := avformatLOCAL_SRC_FILES := libavformat-57.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := avutilLOCAL_SRC_FILES := libavutil-55.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := swscaleLOCAL_SRC_FILES := libswscale-4.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := swresampleLOCAL_SRC_FILES := libswresample-2.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := avdeviceLOCAL_SRC_FILES := libavdevice-57.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := postprocLOCAL_SRC_FILES := libpostproc-54.soinclude $(PREBUILT_SHARED_LIBRARY)# Programinclude $(CLEAR_VARS)LOCAL_MODULE := jniloaderLOCAL_SRC_FILES := jniloader.cLOCAL_C_INCLUDES += $(LOCAL_PATH)/includeLOCAL_LDLIBS := -llog -lzLOCAL_SHARED_LIBRARIES := avcodec avdevice avfilter avformat avutil postproc swresample swscaleinclude $(BUILD_SHARED_LIBRARY)
Application.mk
APP_ABI :=armeabi
jniloader.c
#include <stdio.h>#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#include "libavfilter/avfilter.h" #ifdef ANDROID#include <jni.h>#include <android/log.h>#endifstruct URLProtocol; JNIEXPORT jstring Java_com_example_ffmpeg_JNILoader_urlprotocolinfo(JNIEnv *env, jobject obj){ char info[40000]={0}; av_register_all(); struct URLProtocol *pup = NULL; //Input struct URLProtocol **p_temp = &pup; avio_enum_protocols((void **)p_temp, 0); while ((*p_temp) != NULL){ sprintf(info, "%s[In ][%10s]\n", info, avio_enum_protocols((void **)p_temp, 0)); } pup = NULL; //Output avio_enum_protocols((void **)p_temp, 1); while ((*p_temp) != NULL){ sprintf(info, "%s[Out][%10s]\n", info, avio_enum_protocols((void **)p_temp, 1)); } //LOGE("%s", info); return (*env)->NewStringUTF(env, info); }JNIEXPORT jstring Java_com_example_ffmpeg_JNILoader_avformatinfo(JNIEnv *env, jobject obj){ char info[40000] = { 0 }; av_register_all(); AVInputFormat *if_temp = av_iformat_next(NULL); AVOutputFormat *of_temp = av_oformat_next(NULL); //Input while(if_temp!=NULL){ sprintf(info, "%s[In ][%10s]\n", info, if_temp->name); if_temp=if_temp->next; } //Output while (of_temp != NULL){ sprintf(info, "%s[Out][%10s]\n", info, of_temp->name); of_temp = of_temp->next; } //LOGE("%s", info); return (*env)->NewStringUTF(env, info); } JNIEXPORT jstring Java_com_example_ffmpeg_JNILoader_avcodecinfo(JNIEnv *env, jobject obj) { char info[40000] = { 0 }; av_register_all(); AVCodec *c_temp = av_codec_next(NULL); while(c_temp!=NULL){ if (c_temp->decode!=NULL){ sprintf(info, "%s[Dec]", info); } else{ sprintf(info, "%s[Enc]", info); } switch (c_temp->type){ case AVMEDIA_TYPE_VIDEO: sprintf(info, "%s[Video]", info); break; case AVMEDIA_TYPE_AUDIO: sprintf(info, "%s[Audio]", info); break; default: sprintf(info, "%s[Other]", info); break; } sprintf(info, "%s[%10s]\n", info, c_temp->name); c_temp=c_temp->next; } //LOGE("%s", info); return (*env)->NewStringUTF(env, info); } JNIEXPORT jstring Java_com_example_ffmpeg_JNILoader_avfilterinfo(JNIEnv *env, jobject obj) { char info[40000] = { 0 }; avfilter_register_all(); AVFilter *f_temp = (AVFilter *)avfilter_next(NULL); while (f_temp != NULL){ sprintf(info, "%s[%10s]\n", info, f_temp->name); f_temp = f_temp->next; } //LOGE("%s", info); return (*env)->NewStringUTF(env, info); } JNIEXPORT jstring Java_com_example_ffmpeg_JNILoader_configurationinfo(JNIEnv *env, jobject obj) { char info[10000] = { 0 }; av_register_all(); sprintf(info, "%s\n", avcodec_configuration()); //LOGE("%s", info); return (*env)->NewStringUTF(env, info); }
然后就用NDK编译即可,这就是我们最终要的了。
三.Java层调用接口
把JNI编译出来的SO库放在jniLibs下
声明相关的c层函数并加载so库
最后调用即可,这些都只是简单的用ffmpeg提供的函数输出相关的配置信息,还有很多强大的音视频相关的功能要慢慢探索了。
阅读全文
0 0
- Android:WIN10+MinGW+NDK编译FFmpeg
- android ndk 编译 ffmpeg
- Android NDK编译ffmpeg
- Win10 64位下用minGW编译64位FFMpeg
- 用Android NDK编译FFmpeg
- 用Android NDK编译FFmpeg
- 用Android NDK编译FFmpeg
- 用Android NDK编译FFmpeg
- 用Android NDK编译FFmpeg
- 使用Android NDK编译ffmpeg
- android 用ndk编译ffmpeg
- 用Android NDK编译FFmpeg
- 用Android NDK编译FFmpeg
- 用Android NDK编译FFmpeg
- android ndk 编译ffmpeg+x264
- 【Android】用NDK编译Ffmpeg
- 用Android NDK编译FFmpeg
- 用Android NDK编译FFmpeg
- 统计立方数 oj99
- 现代前端技术解析:Web前端技术基础
- Splay树
- What Is Your Grade?
- Struts2文件上传下载和表单重复提交问题
- Android:WIN10+MinGW+NDK编译FFmpeg
- 国产数据库——神通数据库的安装使用
- HDU1789 解题报告
- 【Caffe的C++接口使用说明五)】win10+cuda7.5+caffe+vs2013环境搭建(CPU版本)
- LVS系列—LVS的三种工作方式(DR原理)(二)
- Java基础知识3
- 【简单计算】 oj102
- 图像处理3:摄像头捕获视频
- Set,List, Map各自实现类的比较