编译Android下可执行命令的FFmpeg


请尊重原创,转载请注明出处:http://blog.csdn.net/mabeijianxi/article/details/72904694


本人环境与工具:


  • ndk:r14
  • FFmpeg版本: 3.2.5
  • Android Studio: 2.3.2

一、说明:


本文是经过实战总结出的经验,本文将用两种方式编译可以在Android下执行命令的FFmpeg,一种是传统的ndk-build工具,一种是cmake工具,经过我的项目实战,非常推荐cmake,因为AS 2.2以后对它支持的非常好,你可以非常方便的像debug Java代码一样去debug Native代码。本文以是在假设已经编译好了全架构的 FFmpeg 的基础上进行的,编译步骤: 编译Android下可用的全平台FFmpeg(包含libx264与libfdk-aac)

二、传统ndk-build命令编译


所谓传统,必然就稍微没那么智能了,我们一步一步的搞。

  1. 打开你养家糊口的Android Studio,娴熟的新建一个项目;
  2. 编写一个 native 函数,如果只是测试我们在MainActivity里面搞就行了:

    public native int ffmpegRun(String[] cmd);
  3. 新建jni目录,在目录下新建文件: jx_ffmpeg_cmd_run.c;

  4. 编码对应的 JNI 接口:

    #include <jni.h><br>
    JNIEXPORT jint JNICALL
    Java_com_mabeijianxi_jianxiffmpegcmd_MainActivity_ffmpegRun(JNIEnv *env, jobject instance, jobjectArray cmd) {
    
     // TODO
    }
  5. 找到我们FFmpeg编译后的根目录,然后 copy:
    cmdutils.c cmdutils.h cmdutils_common_opts.h config.h ffmpeg.c ffmpeg.h ffmpeg_filter.c ffmpeg_opt.c(注意需要编译后才会有config.h)到 jni 目录下,再进入到我们的编译后的产物目录,把include文件夹与所有的 .so 动态库也 copy 到jni目录下。完成后你jni目录结构应该如下图:


  6. 文件修改
    修改ffmpeg.c与ffmpeg.h
    找到ffmpeg.c,把int main(int argc, char argv) 改名为 int jxRun(int argc, char argv)
    找到ffmpeg.h, 在文件末尾添加函数申明: int jxRun(int argc, char **argv);



    1)修改cmdutils.c 和 cmdutils.h
    找到cmdutils.c中的exit_program函数
    修改前:



    修改后:



    2)找到cmdutils.h中exit_program的申明,也把返回类型修改为int。
    修改前:



    修改后:



    很多教程都只修改到这里,基本没什么问题,但是你实际运行的时候会发现如果连续多次执行命令会有问题的,通过源码我们可以知道,FFmpeg每次执行完命令后会调用 ffmpeg_cleanup 函数清理内存,并且会调用exit(0)结束当前进程,但是经过我们的修改,exit()的代码已经被删掉,我们在Android中自然不能结束当前进程了,所以有些变量的值还在内存中,这样就会导致下次执行的时候可能会出错。我也尝试过fork一个进程给ffmpeg执行,完事后通过 信号来进程间通信,这样管用但是很麻烦,我们其实只需要简单的重设一些变量即可。
    打开ffmpeg.c找到刚修改的jxRun函数,然后在 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;
  7. 编写调用函数
    我们上面只在jx_ffmpeg_cmd_run.c新建了一个JNI接口函数,还没有实现逻辑,我们实现后的代码如下:

    **
    * Created by jianxi on 
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值