android studio ffmpeg simple use (command line)

compile ffmpeg

android studio new project, check it

Throw the compiled libffmpeg.so library to src/main/jniLibs/armeabi (mainly here I only compiled arm's ffmpeg library) 

New file com.jni.FFmpegCmd

package com.jni;

public class FFmpegCmd {

    static {
        System.loadLibrary("ffmpeg");
        System.loadLibrary("ffmpeg-cmd");
    }

    public static native int run(String[] commands);

}

 Create a ffmpeg-cmd.cpp file under cpp (that is, the directory with native-lib.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 = 0; i < argc; i++) {
        jstring js = (jstring) env->GetObjectArrayElement(commands, i);
        argv[i] = (char *) env->GetStringUTFChars(js, 0);
    }
    LOGD( " ===========Start command line execution =========== " );
     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

 

Copy the ffmpeg source files cmdutils.c cmdutils.h ffmpeg.cffmpeg_filter.cffmpeg_opt.c ffmpeg_hw.c to the cpp directory

The folder include lib compiled by ffmpeg is also copied to this directory

Modify ffmpeg.h to add int main(int argc, char **argv) at the end;

Modify ffmpeg.c

Add it at the end of the main method (I heard that it is to prevent the flashback problem in order to repeatedly execute the ffmpeg command)

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;
Modify cmdutils.h
Before modification   void exit_program( int ret) av_noreturn;
After modification   int exit_program( int ret);

Before modification   void show_help_children( const AVClass * class , int flags); // If you don't modify it, there will always be an error in the compilation. 
After modification   void show_help_children( const AVClass *avClass, int flags);

Modify cmdutils.c

void exit_program( int ret) before modification

{
    if (program_exit)
        program_exit(ret);

    exit(ret);
}
after modification
int exit_program(int ret)
{
    if (program_exit)
        program_exit(ret);

    return ret;
}

 CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

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)

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)

This mainly needs to deal with the red part, other parts are automatically generated

Finally test it in MainActivity.java

public class MainActivity extends AppCompatActivity {

    private ExecutorService es = Executors.newSingleThreadExecutor();
    String path = Environment.getExternalStorageDirectory().getPath();

    private ProgressDialog progressDialog;
    private TextView tv;


    @Override
    protected  void onCreate (Bundle savedInstanceState) {
         super .onCreate (savedInstanceState);
        setContentView(R.layout.activity_main);

        tv = findViewById(R.id.sample_text);
        tv.setText( "Test" );


        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 to ts -y will overwrite the file if it has the same name. If you don't add -y, you will be prompted whether there is a file with the same name overwritten. If you execute it again, it will flash back.
                        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( "Processed successfully" );
                                }else{
                                    tv.setText( "Processing failed" );
                                }
                            }
                        });
                    }
                }).start();
            }
        });
    }

}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325096498&siteId=291194637