编译ffmpeg

android studio 新建项目,勾选上

将编译好的libffmpeg.so库扔到src/main/jniLibs/armeabi下(主要这里我只编译了arm的ffmpeg的库)

新建文件com.jni.FFmpegCmd

package com.jni;

public class FFmpegCmd {

    static {
System.loadLibrary("ffmpeg");
System.loadLibrary("ffmpeg-cmd");
} public static native int run(String[] commands); }

在cpp下 (即有native-lib.cpp的目录) 创建一个ffmpeg-cmd.cpp文件

#include <jni.h>
#include "ffmpeg.h"
#include "android_log.h" extern "C" JNIEXPORT jint JNICALL
Java_com_jni_FFmpegCmd_run(JNIEnv *env, jobject, jobjectArray commands) {
int argc = env->GetArrayLength(commands);
char *argv[argc];
for (int i = ; i < argc; i++) {
jstring js = (jstring) env->GetObjectArrayElement(commands, i);
argv[i] = (char *) env->GetStringUTFChars(js, );
}
LOGD("============开始执行命令行===========");
return main(argc, argv);
}

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

拷贝ffmpeg源码文件 cmdutils.c cmdutils.h ffmpeg.cffmpeg_filter.cffmpeg_opt.c ffmpeg_hw.c 到cpp目录下

(ffmpeg-3.4之前的版本 不需要ffmpeg_hw.c文件,但是需要cmdutils_common_opts.h文件)

ffmpeg编译后的文件夹include lib也拷贝到该目录

修改ffmpeg.h 在最后添加    int main(int argc, char **argv);

修改ffmpeg.c

在main方法最后添加(听说是为了防止为了重复执行ffmpeg命令闪退问题)

nb_filtergraphs = ;
progress_avio = NULL; input_streams = NULL;
nb_input_streams = ;
input_files = NULL;
nb_input_files = ; output_streams = NULL;
nb_output_streams = ;
output_files = NULL;
nb_output_files = ;
修改cmdutils.h
修改前  void exit_program(int ret) av_noreturn;
修改后 int exit_program(int ret); 修改前 void show_help_children(const AVClass *class, int flags);//不修改的话编译一直出错 (可能是class关键字的原因,关键字不能当变量使用)
修改后 void show_help_children(const AVClass *avClass, int flags);

修改cmdutils.c

修改前
void exit_program(int ret)
{
if (program_exit)
program_exit(ret); exit(ret);
}
修改后
int exit_program(int ret)
{
if (program_exit)
program_exit(ret); return ret;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.)

add_library(ffmpeg-cmd
SHARED
src/main/cpp/cmdutils.c
src/main/cpp/ffmpeg.c
src/main/cpp/ffmpeg_filter.c
src/main/cpp/ffmpeg_opt.c
src/main/cpp/ffmpeg_hw.c
src/main/cpp/ffmpeg-cmd.cpp) find_library(log-lib
log
android)

#这里红色部分对应上面拷贝的两个文件夹路径,这里也可以不用拷贝这两个文件夹,直接把下面两行红色部分给成你电脑上编译好的ffmpeg的include和lib的路径
include_directories(src/main/cpp/include
src/main/cpp/lib
E:/ffmpeg/4.0/build/ffmpeg-4.0)
add_library(ffmpeg SHARED IMPORTED)
set_target_properties(ffmpeg PROPERTIES IMPORTED_LOCATION E:/ffmpeg/4.0/build/android/arm/libffmpeg.so) target_link_libraries(
ffmpeg-cmd
ffmpeg
android
${log-lib} )

build.gradle(Module:app)

这里主要需要处理红色圈圈部分,其他部分都是自动生成的

最后在MainActivity.java 测试一下

public class MainActivity extends AppCompatActivity {

    private ExecutorService es = Executors.newSingleThreadExecutor();
String path = Environment.getExternalStorageDirectory().getPath(); private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE" }; private ProgressDialog progressDialog;
private TextView tv; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
//检测是否有写的权限
int permission = ActivityCompat.checkSelfPermission(activity,
"android.permission.WRITE_EXTERNAL_STORAGE");
if (permission != PackageManager.PERMISSION_GRANTED) {
// 没有写的权限,去申请写的权限,会弹出对话框
ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);
}
} catch (Exception e) {
e.printStackTrace();
} tv = findViewById(R.id.sample_text);
tv.setText("测试"); tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressDialog = ProgressDialog.show(MainActivity.this,"","处理中");
new Thread(new Runnable() {
@Override
public void run() {
String str = "ffmpeg -i %s -vcodec copy -f mpegts -y %s";//mp4 转 ts -y如果有同名名则覆盖文件。不加-y则会提示有同名文件是否覆盖,这里再次执行的话会闪退
String commandStr = String.format(str,path+"/data/qq.mp4",path+"/data/qq.ts");
String[] commands = commandStr.split("\\s+");
for(String command:commands){
Log.d(MainActivity.class.getName(),"command="+command);
}
final int sum = FFmpegCmd.run(commands); new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if(sum == 0){
if(progressDialog != null){
progressDialog.dismiss();
}
tv.setText("处理成功");
}else{
tv.setText("处理失败");
}
}
});
}
}).start();
}
});
} }

AndroidManifest.xml 需要添加权限

<!--网络连接-->
<uses-permission android:name="android.permission.INTERNET" />
<!--sd卡读写 6.0以上系统可能还需要动态申请sd卡读写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

android studio ffmpeg简单使用 (cmake)的更多相关文章

  1. Android Studio IDE 简单学习和介绍

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  2. 通过android studio的gradle强制cmake输出命令详情

    https://stackoverflow.com/questions/43439549/force-cmake-in-verbose-mode-via-gradle-and-the-android- ...

  3. Android Studio 超级简单的打包生成apk

    为什么要打包: apk文件就是一个包,打包就是要生成apk文件,有了apk别人才能安装使用.打包分debug版和release包,通常所说的打包指生成release版的apk,release版的apk ...

  4. Android Studio一些简单设置

          简单设置   1.默认主题设置 默认的 Android Studio 为灰色界面,能够选择使用炫酷的黑色界面. Settings --> Appearance --> Them ...

  5. android studio 2.2 使用cmake编译NDK

    Android studio 2.2 已经进入beta版本,新功能添加众多,NDK编程也得到了简化.官方博客介绍.本文介绍如何使用新版android studio调用 c++代码,为了超级通俗易懂,例 ...

  6. Android Studio的简单设置:

    4.关闭更新: 如下图所示: 6.添加api文档悬浮提示: AS默认是没有api文档悬浮提示的,只有按住[Ctrl+Q]太会出现提示.如果要添加api的自动悬浮提示,设置如下: 上图中,在红框部分打钩 ...

  7. 在Android Studio进行“简单配置”单元测试(Android Junit)

    起因 在Android studio 刚出.本人就想弄单元测试,可惜当时Android studio不知道抽什么风(准确来说,应该是我不会弄而已).无法执行到相应的代码.后来今天突然自己又抽风.又想去 ...

  8. 重大发现Android studio 如何简单快速修改package name

    好多人都发现Android studio修改包名比较麻烦,只能一级一级的修改,今天偶尔发现了一个快捷方法. 废话不多说: 1 打开项目的AndroidManifest.xml文件 2 鼠标光笔定位到你 ...

  9. Android studio实现简单的CRUD

    1.打开Android studio ,创建项目DataBase01 2.进行UI设计,如图 目的:实现对姓名及其爱好的增删改查 3.创建DB.java,用于创建数据库,并做相关操作 在该目录下右键- ...

随机推荐

  1. 7.JavaScript变量

    VAR声明变量,一条语句可以声明多个变量 var name="Gates", age=56, job="CEO"; Value = undefined 在计算机 ...

  2. Javascript - ERR_CONTENT_LENGTH_MISMATCH

    不知道做了什么,有两天没有跑vue项目啦,今天突然出现加载脚本的时候出现 ERR_CONTENT_LENGTH_MISMATCH这个错误, 所以我去搜索了一下  找到如下答案  http://stac ...

  3. POJ 1088 滑雪 ( DFS+动态规划思想 )

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 79519   Accepted: 29581 Description ...

  4. python生成图片

    # -*- coding:utf-8 -*- from pylab import * figure(1,figsize=(6,6)) ax = axes([0.1,0.1,0.8,0.8]) frac ...

  5. servlet串行拦截器实现例子

    至于串行过滤器有什么作用,我实在不知.我的理解是它只是说明 过滤器的串行运行方式 需求:当用户没有登录访问更新页面的时候,跳转到登录页面 1.登录页面:login.jsp <%@ page la ...

  6. 什么是HTTP协议?

    HTTP协议(超文本传输协议)位于TCP/IP协议栈的应用层.传输层采用面向连接的TCP HTTP请求详细过程

  7. Android终端管理器删除文件夹

    终端管理器删除文件夹不能用网上提供的: rm -rf 文件夹名 而要用: rm -r 文件夹名. http://blog.csdn.net/enhancing/article/details/8490 ...

  8. spring boot 部署 发布

    Spring Boot应用的打包和部署 字数639 阅读2308 评论0 喜欢5 现在的IT开发,DevOps渐渐获得技术管理人员支持.云计算从ECS转向Docker容器技术.微服务的概念和讨论也越来 ...

  9. FFmpeg常用命令 (三)流媒体

    前言 如此强大的FFmpeg,能够实现视频采集.视频格式转化.视频截图.视频添加水印.视频切片.视频录制.视频推流.更改音视频参数功能等.通过终端命令如何实现这些功能,Richy在本文做一记录,以备之 ...

  10. PBE加密算法

    这是我参加全国信息安全大赛的设计的加密系统中的一个加密算法,虽然比赛的结果不是非常理想但是,我还是学到了很多东西,现在和大家分享一下,比赛收获的东西. 基于口令加密 PBE(Password Base ...