Ubuntu编译android版ffmpeg
来源:互联网 发布:零基础学python张志强 编辑:程序博客网 时间:2024/06/07 02:24
准备材料:ffmpeg源码,NDK环境
去ffmpeg官网下载ffmpeg源码。我的为ffmpeg-2.6.2。进入ffmpeg的目录。编写编译脚本文件android_ffmpeg.sh.内容如下
NDK=/home/hxl/bin/android-ndk-r10d SYSROOT=$NDK/platforms/android-9/arch-arm/ TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64 function build_one { ./configure \ --prefix=$PREFIX \--enable-nonfree \--enable-shared \ --enable-gpl \ --enable-static \ --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 cleanmake -j$THREAD_COUNTmake install} CPU=arm PREFIX=$(pwd)/android/$CPU ADDI_CFLAGS="-marm" build_one
注意将NDK_ROOT换为你自己的路径。
然后chmod 777 android_ffmpeg.sh 给该文件添加权限。最后执行./android_ffmpeg.sh 就进行编译了。编译完成后进入ffmpeg目录你会发现多出来一个android文件夹,在android/arm/lib下面就是编译出来的.a的静态库和.so的分享库。我的编译过程也是参考网上的给出的编译脚本代码完成的。需要注意的一点是如果直接copy脚本代码有可能会有一些格式上面的问题而导致编译失败。最后我会将脚本文件直接上传,有需要的可以下载。
参考网址:http://blog.csdn.net/gobitan/article/details/22750719
这样编出来的so包的名字存在像这样avcodec.so.54这样的文件,也存在不带数字的.so文件,android识别不出来。解决办法如下:
将ffmpeg的config文件的以下四行:
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)'
编译出来的就以.so结尾了,原来的avcodec.so.54这样的文件变为了avcodec.54.so这样的文件,但有点疑问的是在mk文件中引用的都是带数字的so包,使用不带数字的so包编译出来的会提示dlopen failed: could not load library "libavutil-54.so" needed by "libswresample.so"; caused by library "libavutil-54.so" not found 的error,都换为带数字的so文件时就可以正正确使用啦。不明白原因,有知道的希望能给留言赐教。
现在写一个android项目测试下是否编译成功。
具体步骤仿照文章:
我贴下我的代码Android.mk文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE :=avcodec-prebuilt LOCAL_SRC_FILES :=prebuilt/libavcodec-56.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE :=avdevice-prebuilt LOCAL_SRC_FILES :=prebuilt/libavdevice-56.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE :=avfilter-prebuilt LOCAL_SRC_FILES :=prebuilt/libavfilter-5.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE :=avformat-prebuilt LOCAL_SRC_FILES :=prebuilt/libavformat-56.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE :=swresample-prebuilt LOCAL_SRC_FILES :=prebuilt/libswresample-1.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := avutil-prebuilt LOCAL_SRC_FILES :=prebuilt/libavutil-54.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := postproc-prebuilt LOCAL_SRC_FILES :=prebuilt/libpostproc-53.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := swscale-prebuilt LOCAL_SRC_FILES :=prebuilt/libswscale-3.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE :=ffmpeg_lily_codec LOCAL_SRC_FILES :=com_lily_testffmpeg_FFmpegExample.c \ LOCAL_LDLIBS :=-llog -ljnigraphics -lz -landroid LOCAL_SHARED_LIBRARIES:= avcodec-prebuilt avdevice-prebuilt avfilter-prebuilt avformat-prebuilt avutil-prebuilt swscale-prebuilt swresample-prebuilt include $(BUILD_SHARED_LIBRARY)
对于这段mk文件的解释,感谢:http://blog.csdn.net/smfwuxiao/article/details/8523479
I. 声明一个预编译库的模块
对于Android编译工具而言,每个预编译库必须声明为一个独立的模块。这里举一个例子,假设 libfoo.so 文件与 Android.mk 位于同一个目录:- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_MODULE := foo-prebuilt
- LOCAL_SRC_FILES := libfoo.so
- include $(PREBUILT_SHARED_LIBRARY)
1. 给该模块取一个名字(这里是 foo-prebuilt)。这个名字不需要与预编译库自身的名字相同。
2. 将 LOCAL_SRC_FILES 指定为你要提供的共享库的路径。通常,该路径是相对于 LOCAL_PATH 的路径。注意:必须保证共享库ABI的兼容性。
3. 如果你的库是共享库,则包含 PREBUILT_SHARED_LIBRARY 而不是 BUILD_SHARED_LIBRARY;如果是静态库,则包含 PREBUILT_STATIC_LIBRARY。
预编译模块不需要编译。该预编译模块会被拷贝到 $PROJECT/obj/local 下面,还会被拷贝到 $PROJECT/libs/<abi> 下面(这里的库被strip过)。
II. 在其他模块中引用这个预编译库
在依赖该预编译库的模块对应的Android.mk中,将预编译库的名字(前面取的)加入到 LOCAL_STATIC_LIBRARIES 或 LOCAL_SHARED_LIBRARIES 声明中。例如,一个使用上面libfoo.so的简单例子如下:
- include $(CLEAR_VARS)
- LOCAL_MODULE := foo-user
- LOCAL_SRC_FILES := foo-user.c
- LOCAL_SHARED_LIBRARIES := foo-prebuilt
- include $(BUILD_SHARED_LIBRARY)
FFmpegExample.java
package com.lily.testffmpeg;public class FFmpegExample {static{ System.loadLibrary("swresample-1");System.loadLibrary("avcodec-56"); System.loadLibrary("avdevice-56"); System.loadLibrary("avfilter-5"); System.loadLibrary("avformat-56"); System.loadLibrary("avutil-54"); System.loadLibrary("postproc-53"); System.loadLibrary("swscale-3"); System.loadLibrary("ffmpeg_lily_codec");} public native int lilyavcodec_findcodec(int id); }
com_lily_testffmpeg_FFmpegExample.h
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_lily_testffmpeg_FFmpegExample */#ifndef _Included_com_lily_testffmpeg_FFmpegExample#define _Included_com_lily_testffmpeg_FFmpegExample#ifdef __cplusplusextern "C" {#endif/* * Class: com_lily_testffmpeg_FFmpegExample * Method: lilyavcodec_findcodec * Signature: (I)I */JNIEXPORT jint JNICALL Java_com_lily_testffmpeg_FFmpegExample_lilyavcodec_1findcodec (JNIEnv * env, jobject obj, jint id);#ifdef __cplusplus}#endif#endif
com_lily_testffmpeg_FFmpegExample.c
#include "com_lily_testffmpeg_FFmpegExample.h"#include <math.h>#include <libavutil/opt.h>#include <libavcodec/avcodec.h>#include <libavutil/channel_layout.h>#include <libavutil/common.h>#include <libavutil/imgutils.h>#include <libavutil/mathematics.h>#ifdef __cplusplusextern "C" {#endif/* * Class: cn_dennishucd_FFmpegNative * Method: avcodec_find_decoder * Signature: (I)I */JNIEXPORT jint JNICALL Java_com_lily_testffmpeg_FFmpegExample_lilyavcodec_1findcodec (JNIEnv * env, jobject obj, jint id){AVCodec *codec = NULL;/* register all formats and codecs */av_register_all();codec = avcodec_find_decoder(id);if (codec != NULL){return 0;}else{return -1;}}#ifdef __cplusplus}#endif
MainActivity.java
package com.lily.testffmpeg;import com.example.testandroidsp.R;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.TextureView;import android.widget.TextView;public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv=(TextView) findViewById(R.id.tv);FFmpegExample fFmpegExample = new FFmpegExample(); int codecID = 28; //28 is the H264 Codec ID int res = fFmpegExample.lilyavcodec_findcodec(codecID); if(res ==0) { tv.setText("Success!"); } else{ tv.setText("Failed!"); } }}
特别鸣谢:http://blog.csdn.net/gobitan/article/details/22750719
编译脚本文件http://download.csdn.net/detail/u010095768/8703265
例子源码:http://download.csdn.net/detail/u010095768/8703311
- Ubuntu编译android版ffmpeg
- 在Ubuntu中用Android NDK编译FFmpeg
- 在Ubuntu中用Android NDK编译FFmpeg
- 在Ubuntu中用Android NDK编译FFmpeg
- 在Ubuntu中用Android NDK编译FFmpeg
- 在Ubuntu中用Android NDK编译FFmpeg
- 在Ubuntu中用Android NDK编译FFmpeg
- ubuntu中使用android ndk编译ffmpeg.
- 在Ubuntu中用Android NDK编译FFmpeg
- Ubuntu 14.10+NDK+ffmpeg编译+Android
- Ubuntu下FFmpeg-Android-master编译过程
- ubuntu 平台 FFmpeg Android .so文件编译
- Android Ubuntu下FFmpeg的编译教程
- Ubuntu编译Android使用的FFmpeg
- FFmpeg For Android (二) Ubuntu下编译FFmpeg源码
- FFmpeg学习—ubuntu 下编译 Android ffmpeg
- vm+ubuntu+ffmpeg编译
- ubuntu 10.04 编译ffmpeg
- CSS中什么时候用id什么时候用class
- 最长公共子序列
- Codeforces544D:Destroying Roads(最短路)
- XDOJ 猴子吃桃
- mysql --建索引
- Ubuntu编译android版ffmpeg
- kmp算法
- 使用JNI调用dll(C++)
- 添加复位键按钮
- mysql root用户的密码修改和消除
- Android 多图片情况下,发生内存溢出的解决办法
- 堆排序
- 写存储过程
- ant之build.xml详解