Unbantu 编译ffmpeg Android版本库
来源:互联网 发布:php 请求超时设置 编辑:程序博客网 时间:2024/05/18 04:55
首先需要去FFmpeg的官网http://www.ffmpeg.org/去下载FFmpeg的源码,目前的版本号为FFmpeg3.3(Hilbert)。
下载的文件为压缩包,解压后得到ffmpeg-3.3目录。
修改ffmpeg-3.3的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)'
原因:如果不修改配置,直接进行编译出来的so文件类似libavcodec.so.55.39.101,文件的版本号位于so之后,这样在Android上无法加载,所以需要修改!
编写build_android.sh脚本文件:
在编译FFmpeg之前需要进行配置,设置相应的环境变量等。所有的配置选项都在ffmpeg-3.3/configure这个脚本文件中,执行如下命令可查看所有的配置选项:
$ ./configure –help
下面将配置项和环境变量设置写成一个sh脚本文件来运行以便编译出Android平台需要的so文件出来。
build_android.sh的内容如下:
#!/bin/bash
NDK=/Users/renhui/framework/android-ndk-r14b
SYSROOT=$NDK/platforms/android-9/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
function build_one
{
./configure \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffserver \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
}
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
build_one
需要确定的是NDK,SYSROOT和TOOLCHAIN是否是本地的环境,并确定cross-prefix指向的路径存在。
保存脚本文件后,将脚本的权限提升:
chmod 777 build_android.sh
然后执行脚本,该脚本会完成对ffmpeg的配置,并生成config.h等配置文件,后面的编译会用到。如果未经过配置直接进行编译会提示无法找到config.h文件等错误。
然后执行下面两个命令:
$make
$make install
至此,会在ffmpeg-3.3目录下生成一个android目录,其/android/arm/lib目录下的so库文件就是能够在Android上运行的so库。
创建Demo工程,测试上面生成的so文件能否正常使用:
创建一个新的Android工程
在工程根目录下创建jni文件夹
在jni下创建prebuilt目录,然后:将上面编译成功的so文件放入到该目录下
创建包含native方法的类,先在src下创建cn.renhui包,然后创建FFmpegNative.java类文件。主要包括加载so库文件和一个native测试方法两部分,其内容如下:
package cn.renhui;
public class FFmpegNative {
static {
System.loadLibrary("avutil-55");
System.loadLibrary("avcodec-57");
System.loadLibrary("swresample-2");
System.loadLibrary("avformat-57");
System.loadLibrary("swscale-4");
System.loadLibrary("avfilter-6");
System.loadLibrary("avdevice-57");
System.loadLibrary("ffmpeg_codec");
}
public native int avcodec_find_decoder(int codecID);
}
用javah创建.头文件: classes目录,执行:javah-jni cn.renhui.FFmpegNative,会在当前目录产生cn_renhui_FFmpegNative.h的C头文件;
根据头文件名,建立相同名字c文件cn_renhui_FFmpegNative.c,在这个源文件中实现头文件中定义的方法,代码如下:
#include "cn_renhui_FFmpegNative.h"
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_cn_renhui_FFmpegNative_avcodec_1find_1decoder
(JNIEnv *env, jobject obj, jint codecID)
{
AVCodec *codec = NULL;
/* register all formats and codecs */
av_register_all();
codec = avcodec_find_decoder(codecID);
if (codec != NULL)
{
return 0;
}
else
{
return -1;
}
}
#ifdef __cplusplus
}
#endif
编写Android.mk,内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := avcodec-57-prebuilt
LOCAL_SRC_FILES := prebuilt/libavcodec-57.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avdevice-57-prebuilt
LOCAL_SRC_FILES := prebuilt/libavdevice-57.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avfilter-6-prebuilt
LOCAL_SRC_FILES := prebuilt/libavfilter-6.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avformat-57-prebuilt
LOCAL_SRC_FILES := prebuilt/libavformat-57.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avutil-55-prebuilt
LOCAL_SRC_FILES := prebuilt/libavutil-55.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avswresample-2-prebuilt
LOCAL_SRC_FILES := prebuilt/libswresample-2.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swscale-4-prebuilt
LOCAL_SRC_FILES := prebuilt/libswscale-4.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg_codec
LOCAL_SRC_FILES := cn_dennishucd_FFmpegNative.c
LOCAL_LDLIBS := -llog -ljnigraphics -lz -landroid
LOCAL_SHARED_LIBRARIES := avcodec-57-prebuilt avdevice-57-prebuilt avfilter-6-prebuilt avformat-57-prebuilt avutil-55-prebuilt
include $(BUILD_SHARED_LIBRARY)
编译so文件,执行ndk-build
新建一个Activity,进行测试,测试核心代码:
FFmpegNative ffmpeg = new FFmpegNative();
int codecID = 28;
int res = ffmpeg.avcodec_find_decoder(codecID);
if (res == 0) {
tv.setText("Success!");
} else {
tv.setText("Failed!");
}
28是H264的编解码ID,可以在ffmpeg的源代码中找到,它是枚举类型定义的。在C语言中,可以换算为整型值。这里测试能否找到H264编解码,如果能找到,说明调用ffmpeg的库函数是成功的,这也表明我们编译的so文件是基本可用。
- Unbantu 编译ffmpeg Android版本库
- 编译FFMPEG Android版本
- FFmpeg编译Android版本
- ffmpeg源码编译android版本
- mac编译Android版本ffmpeg的x86_64架构库
- 编译Android版本FFmpeg 2.0小结
- Ffmpeg编译Android库
- 编译FFMpeg的Android版本,并整合到android studio
- FFmpeg+x264编译Android库
- android ffmpeg 动态库编译
- mac 平台下编译android版本 ffmpeg+h264
- Compile FFmpeg for Android(编译用于android的FFmpeg库)
- FFMPEG release版本编译出错
- FFmpeg完美编译iOS版本
- FFmpeg 1.2 for Android 编译动态库
- 编译ffmpeg生成Android动态库
- ffmpeg编译动态库4Android
- FFmpeg学习—Android 编译x264 库
- 统计单词个数
- tgtadm和iscsiadm命令的用法
- hibernate映射文件class元素属性详解
- C++的多重继承
- VAssistX 添加inclue查找路径支持语法高亮(举例:兼容Qt导入项目)
- Unbantu 编译ffmpeg Android版本库
- ubuntu下安装teamviewer
- CentOS7通过yum安装Mysql5.7+修改默认密码+远程登录
- 237. Delete Node in a Linked List的C++解法
- Scsi-target-utils Quickstart Guide
- Spring源码解析-PropertyEditor
- 使用EasyPermissions 来打造简单的android6.0动态权限
- Linq 和 Lambda 查询中按照多个值进行分组GroupBy
- vue.js浅度监听和深度监听