编译Android环境下Ffmpeg命令行
来源:互联网 发布:华为软件 公司 编辑:程序博客网 时间:2024/06/07 13:58
提示:如果Ubuntu中未搭建android studio、或对Linux系统操作不熟悉的,可拷贝ffmpeg相关文件到windows中进行后续开发。
新建Android项目,并创建一个ffmpeglib的module
尊重原创,转载请注明出处,原文地址: http://blog.csdn.net/qq137722697
接下来所有的编译工作都将在ffmpeglib中进行
新建调用ffmpeg命令行的类
public class Ffmpeg { static { System.loadLibrary("ffmpegrun"); System.loadLibrary("avcodec-57"); System.loadLibrary("avformat-57"); System.loadLibrary("avutil-55"); System.loadLibrary("swscale-4"); } /** * 执行ffmpeg命令行 * * @param cmd * @return */ public native int execute(String[] cmd);}
新建jni目录
在src/main下新建jni目录
新建ffmpeg_run.c
在jni目录中新建ffmpeg_run.c文件,用于作为上面新建的Ffmpeg类调用c代码。
#include "android_log.h"#include "ffmpeg.h"#include <jni.h>JNIEXPORT jint JNICALL Java_com_hdl_ffmpeg_Ffmpeg_execute(JNIEnv *env, jobject type,jobjectArray commands){ int argc = (*env)->GetArrayLength(env,commands); char *argv[argc]; int i; for (i = 0; i < argc; i++) { jstring js = (jstring) (*env)->GetObjectArrayElement(env,commands, i); argv[i] = (char *) (*env)->GetStringUTFChars(env,js, 0); } LOGD("----------begin---------"); return main(argc,argv);}
创建android_log.h
这个主要用于执行命令过程中在logcat中输出日志,便于调试.
在jni目录中创建android_log.h
#ifdef ANDROID#include <android/log.h>#ifndef LOG_TAG#define MY_TAG "MYTAG"#define AV_TAG "AVLOG"#endif#define LOGE(format, ...) __android_log_print(ANDROID_LOG_ERROR, MY_TAG, format, ##__VA_ARGS__)#define LOGD(format, ...) __android_log_print(ANDROID_LOG_DEBUG, MY_TAG, format, ##__VA_ARGS__)#define XLOGD(...) __android_log_print(ANDROID_LOG_INFO,AV_TAG,__VA_ARGS__)#define XLOGE(...) __android_log_print(ANDROID_LOG_ERROR,AV_TAG,__VA_ARGS__)#else#define LOGE(format, ...) printf(MY_TAG format "\n", ##__VA_ARGS__)#define LOGD(format, ...) printf(MY_TAG format "\n", ##__VA_ARGS__)#define XLOGE(format, ...) fprintf(stdout, AV_TAG ": " format "\n", ##__VA_ARGS__)#define XLOGI(format, ...) fprintf(stderr, AV_TAG ": " format "\n", ##__VA_ARGS__)#endif
导入include文件
将上一篇《Ubuntu下编译android所需ffmpeg的so库》中生成的armlib/include文件夹拷贝到jni目录中
导入必备文件
将ffmpeg根目录的
cmdutils.c cmdutils.h cmdutils_common_opts.h
config.h(编译通过之后才会生成)
ffmpeg.c ffmpeg.h ffmpeg_filter.c ffmpeg_opt.c
等文件拷贝到jni目录;
将armlib/lib下所有带有编号的so文件(如libavcodec-57.so)拷贝到jni目录;
修改配置文件
修改cmdutils.c
找到cmdutils.c中的exit_program函数
修改前:
void exit_program(int ret){ if (program_exit) program_exit(ret); exit(ret);}
修改后:
int exit_program(int ret){ if (program_exit) program_exit(ret); // exit(ret); return ret;}
修改cmdutils.h
找到cmdutils.h中的exit_program函数
修改前:
void exit_program(int ret) av_noreturn;
修改后:
int exit_program(int ret);
修改ffmpeg.c
找到main函数,return 之前加上以下代码:(防止连续执行命令崩溃问题)
nb_filtergraphs = 0; progress_avio = NULL; input_streams = NULL; nb_input_streams = 0; input_files = NULL; nb_input_files = 0; output_streams = NULL; nb_output_streams = 0; output_files = NULL; nb_output_files = 0;
新增日志输出【选填】
此选项可选,不需要输出日志到logcat的跳过此项。
找到ffmpeg.c,导入日志的头文件。
include "android_log.h"
找到log_callback_null函数,修改为以下内容(原方法没有任何实现哦):
static void log_callback_null(void *ptr, int level, const char *fmt, va_list vl){ static int print_prefix = 1; static int count; static char prev[1024]; char line[1024]; static int is_atty; av_log_format_line(ptr, level, fmt, vl, line, sizeof(line), &print_prefix); strcpy(prev, line); if (level <= AV_LOG_WARNING){ XLOGE("%s", line); }else{ XLOGD("%s", line); }}
找到main函数,在第一行加入日志输出:
int main(int argc, char **argv){ av_log_set_callback(log_callback_null); int i, ret; int64_t ti; init_dynload(); ... }
打包so
配置Android.mk
鉴于本人对CMake不是非常的熟悉,编译了很多次还是没有成功,后改为Android.mk方式编译。
在jni目录下创建Android.mk文件,并复制以下内容:
LOCAL_PATH := $(call my-dir)# FFmpeg libraryinclude $(CLEAR_VARS)LOCAL_MODULE := avcodecLOCAL_SRC_FILES := libavcodec-57.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := avdeviceLOCAL_SRC_FILES := libavdevice-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 := postprocLOCAL_SRC_FILES := libpostproc-54.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := swresampleLOCAL_SRC_FILES := libswresample-2.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := swscaleLOCAL_SRC_FILES := libswscale-4.soinclude $(PREBUILT_SHARED_LIBRARY)# Programinclude $(CLEAR_VARS)LOCAL_MODULE := ffmpegrunLOCAL_SRC_FILES := ffmpeg_run.c cmdutils.c ffmpeg.c ffmpeg_filter.c ffmpeg_opt.cLOCAL_LDLIBS += -llog#LOCAL_C_INCLUDES += $(LOCAL_PATH)/includeLOCAL_C_INCLUDES :=/home/hdl/ffmpeg/ffmpeg-3.2.9LOCAL_SHARED_LIBRARIES := avcodec avdevice avfilter avformat avutil postproc swresample swscaleinclude $(BUILD_SHARED_LIBRARY)
需要修改的地方:
LOCAL_MODULE:表示生成的so名字;
LOCAL_C_INCLUDES:表示ffmpeg源码的位置
创建Application.mk
复制以下内容:
APP_ABI := armeabi
最后的目录:
打包
进入到jni目录,输入:F:\sdk\ndk-bundle\ndk-build.cmd(此命令表示ndk的路径)
此时会在项目的libs中生成相应的so文件:
测试
在src/main目录下新建一个jniLibs目录,将上面生成的libs下的armeabi文件夹拷贝到jniLibs。
在主工程中编写测试类:(以下为点击按钮,将ts转换为mp4输出)
public void onStartRun(View view) { try { Ffmpeg ffmpegCmd = new Ffmpeg(); /** * 将sdcard中的test.ts文件转换成为output_ts_to_1001.mp4并输出 */ final String dir = Environment.getExternalStorageDirectory().getPath() + File.separator; String cmd = ("ffmpeg -i " + dir + "test.ts -acodec copy -vcodec copy -absf aac_adtstoasc " + dir + "output_ts_to_1001.mp4"); ELog.e(cmd); int execute = ffmpegCmd.execute(cmd.split(" ")); ELog.e("执行完毕了" + execute); } catch (Exception e) { e.printStackTrace(); } }
错误记录:
Android studio会提示Error: Your project contains C++ files but it is not using a supported native build system.大致的意思就是你没有使用cmake来编译:
解决办法:
方法一、将jni目录重命名,如改为jin1,此时就不会报错了;(推荐)
方法二、将jni目录移除(此时已不需要该目录–以后改东西的话还是需要的,推荐方法一)。
E/AVLOG: /storage/emulated/0/test.ts: Permission denied
表示权限拒绝,需要适配权限
尊重原创,转载请注明出处,原文地址: http://blog.csdn.net/qq137722697
- 编译Android环境下Ffmpeg命令行
- Android 环境下编译FFmpeg
- Android下编译ffmpeg
- <android编译ffmpeg+x264+faac> <Android/NDK环境下FFmpeg及AAC,MP3,X264的编译>
- windows环境下编译ffmpeg
- linux下编译ffmpeg环境
- windows环境下android studio 2.3 NDK编译FFmpeg
- Mac环境下编译Android平台的ffmpeg
- Win下命令行编译环境
- mac下编译FFmpeg-Android
- android ndk下编译ffmpeg
- 编译Android下的ffmpeg
- android下ndk编译ffmpeg
- FFMpeg 在Windows 环境下的编译
- FFMpeg在Windows环境下的编译
- ffmpeg 在windows环境下编译
- Xcode 5 环境下编译 ffmpeg 库
- window下搭建C++命令行编译环境
- Storm ack容错机制案例
- 外排序
- java各种后缀邮件勒索病毒文件解密工具解密方法---达康勒索病毒解密中心15169121444
- C# 利用VS自带的WSDL工具生成WebService服务类
- hdu5729思维~~~
- 编译Android环境下Ffmpeg命令行
- AutoCAD .Net 使用 Database.ReadDwgFile 读取dwg文件而不显示文档窗口
- 命令执行下一行代码
- Swift
- [Linux] pip安装python-mysql时报 mysql_config not found pip mysqldb
- HTML+css 个人学习笔记
- 小波变换
- NOIP2015 运输计划 二分答案+Tarjan LCA+树上差分
- 线程--猜数字