FFmpeg 学习(三):将 FFmpeg 移植到 Android平台
首先需要去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-/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 \--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 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 ;
}
else
{
return -;
}
} #ifdef __cplusplus
}
#endif
- 编写Android.mk,内容如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_MODULE := avcodec--prebuilt
LOCAL_SRC_FILES := prebuilt/libavcodec-.so
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE := avdevice--prebuilt
LOCAL_SRC_FILES := prebuilt/libavdevice-.so
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE := avfilter--prebuilt
LOCAL_SRC_FILES := prebuilt/libavfilter-.so
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE := avformat--prebuilt
LOCAL_SRC_FILES := prebuilt/libavformat-.so
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE := avutil--prebuilt
LOCAL_SRC_FILES := prebuilt/libavutil-.so
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE := avswresample--prebuilt
LOCAL_SRC_FILES := prebuilt/libswresample-.so
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE := swscale--prebuilt
LOCAL_SRC_FILES := prebuilt/libswscale-.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--prebuilt avdevice--prebuilt avfilter--prebuilt avformat--prebuilt avutil--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文件是基本可用。
2018年8月20号补充说明:目前最新版本的FFmpeg版本号为4.0.1 ,上面的方法能继续正常使用
FFmpeg 学习(三):将 FFmpeg 移植到 Android平台的更多相关文章
- FFmpeg 学习(五):FFmpeg 编解码 API 分析
在上一篇文章 FFmpeg学习(四):FFmpeg API 介绍与通用 API 分析 中,我们简单的讲解了一下FFmpeg 的API基本概念,并分析了一下通用API,本文我们将分析 FFmpeg 在编 ...
- Windows下将ImageMagick移植到Android平台
Windows下将ImageMagick移植到Android平台 原文链接 http://www.pedant.cn/2014/06/18/imagemagick-ported-android/ I ...
- 基于Cocos2d-x-1.0.1的飞机大战游戏迁移到Cocos2d-x-3.0版本,并移植到Android平台成功运行
一.版本迁移中的问题 1.游戏元素Sprite.Label.Action等等的创建函数名都改为create. 2.函数的回调callfunc_selectorcallfuncN_selectorcal ...
- J2ME项目移植到Android平台六大注意事项
很多J2ME项目如何移植到Android平台呢?Java虽然号称是跨平台应用但是目前的移植问题还是比较严重的,不知道未来Sun推出JavaFx或F3时会出现什么问题,如何从J2ME移植到Android ...
- 将 FFmpeg 移植到 Android平台 (完整版)
首先需要去FFmpeg的官网http://www.ffmpeg.org/去下载FFmpeg的源码,目前的版本号为FFmpeg3.3(Hilbert). 下载的文件为压缩包,解压后得到ffmpeg-3. ...
- FFmpeg 学习(七):FFmpeg 学习整理总结
一.FFmpeg 播放视频的基本流程整理 播放流程: video.avi(Container) -> 打开得到 Video_Stream -> 读取Packet -> 解析到 Fra ...
- FFmpeg 学习(一):FFmpeg 简介
一.FFmpeg 介绍 FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先 ...
- ffmpeg学习笔记-初识ffmpeg
ffmpeg用来对音视频进行处理,那么在使用ffmpeg前就需要ffmpeg有一个大概的了解,这里使用雷神的ppt素材进行整理,以便于复习 音视频基础知识 视频播放器的原理 播放视频的流程大致如下: ...
- Unity3D之移植学习笔记:移植到Android平台更好的方法
接上文,之前我们采用了直接将Unity项目导出为Eclipse项目来修改的方式,这种做法存在的一个最大的问题就是:每当Unity被修改之后,都需要重新导出,而每次导出的项目在Android平台方面的J ...
随机推荐
- Oracle SQL Developer 调试存储过程步骤(Oracle)
1.首先你编译通过你的存储过程,编译的时候一定要选“编译以进行调试”. 2.在想要调试的行上设置好断点. 3.点击“调试”按钮,然后输入存储过程入参,点“确定”开始调试. 4.断点进入后,上方会出现一 ...
- [原创]自定义参数静默方式安装JDK1.8
摘要:当Java桌面程序开发完成做产品的时候,面对未知的安装环境,通常是编写一些预安装检测脚本/程序,让程序傻瓜化安装以便减少分发出去的产品带来 的未知工作量(安装答疑,操作系统问题引起安装失败等), ...
- Visual Studio Installer 设置属性简介
1. 创建安装项目 2.创建项目完成之后,具体各类操作和文件的添加需要自行设置 2.1文件系统 针对文件安装位置,内容进行设置.包括文件,项目输出,程序集 2.2.文件类型(不常用) 设置文件后缀名 ...
- windows 下安装redis
https://github.com/MicrosoftArchive/redis/releases redis 服务安装到系统 redis-server.exe --service-install ...
- 后台跨域(CORS)
解决跨域问题 一.为什么会有跨域问题? 是因为浏览器的同源策略是对ajax请求进行阻拦了,但是不是所有的请求都给做跨域,像是一般的href属性,a标签什么的都不拦截. 二.解决跨域问题的两种方式 JS ...
- 探索未知种族之osg类生物---渲染遍历之裁剪一
前言 上面我们用了四节课的内容,讲解了一些osg概念性的内部原理.希望大家可以再看今天的讲解之前先再仔细的研究一下前四节的内容.这样你就会对整个osg的渲染过程有一个更加清晰的认知,有助于理解下面两个 ...
- IEnumerable对象的Distinct方法重写
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource ...
- 使用QML绘制界面
1 使用QML设计登录界面 https://www.cnblogs.com/bhlsheji/p/5324871.html 2 使用QML实现下拉列表框 https://blog.csdn.net/ ...
- CF Good Bye 2018
前言:这次比赛爆炸,比赛时各种想多,导致写到\(D\)题时思路已经乱了,肝了\(1\)个多小时都没肝出来,\(B\)题中途因为没开\(long\ long\)又被\(HACK\)了..\(C\)题因为 ...
- zxlizsm
好久没发表了,毕业之后就没回来过!