5

I have successfully built ffmpeg for android using the bambuser . Now I have to build a sample converter application like mp4 to 3gp. I know there are command line commands ffmpeg -i video_origine.avi video_finale.mpg. But I don't know how to execute these commands programatically. I have sample code like

jint Java_com_example_ndklearning1_MainActivity_logFileInfo(JNIEnv * env, jobject this, jstring filename)
{
    av_register_all();

    AVFormatContext *pFormatCtx;
    const jbyte *str;
    str = (*env)->GetStringUTFChars(env, filename, NULL);

    if(av_open_input_file(&pFormatCtx, str, NULL, 0, NULL)!=0)
    {
        LOGE("Can't open file '%s'\n", str);
        return 1;
    }
    else
    {
        LOGI("File was opened\n");
        LOGI("File '%s', Codec %s",
            pFormatCtx->filename,
            pFormatCtx->iformat->name
        );

    }
    return 0;
}

This code open's a file and extracts the codec information. All I want is that, to convert the opened file in a desired format. Any kind of help such as code snippet or steps to follow will be highly appreciated.

Can ffmpeg API serve my purpose ? If there is existing API available, it will be more helpful

1 Answer 1

5

Recently I came across the similar problem. My solution is to simulate a command line in Java program.

Firstly, I add a function to the file "ffmpeg.c":

int cmd_simulation(int argc, const char** argv)
{
OptionsContext o = { 0 };
// int64_t ti;

reset_options(&o, 0);

av_log_set_flags(AV_LOG_SKIP_REPEATED);
parse_loglevel(argc, argv, options);

if(argc>1 && !strcmp(argv[1], "-d")){
    run_as_daemon=1;
    av_log_set_callback(log_callback_null);
    argc--;
    argv++;
}

avcodec_register_all();

avfilter_register_all();
av_register_all();
avformat_network_init();

//show_banner(argc, argv, options);

term_init();

parse_cpuflags(argc, argv, options);

/* parse options */
parse_options(&o, argc, argv, options, opt_output_file);

if (nb_output_files <= 0 && nb_input_files == 0) {
    show_usage();
    av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
    exit_program(1);
}


if (nb_output_files <= 0) {
    av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
    exit_program(1);
}

if (transcode() < 0)
    exit_program(1);

//exit_program(0);
return 7;
}

In fact this function is just a copy of the main function with a little modification.

Then create a native function:

extern const char* cmd_simulation(int, const char**);

JNIEXPORT int JNICALL Java_com_test_videowatermark_VideoUtil_test(JNIEnv * env, jobject object, jobjectArray strArray);



JNIEXPORT int JNICALL Java_com_test_videowatermark_VideoUtil_test(JNIEnv * env, jobject object, jobjectArray strArray)
{
    int arrayLength = (*env)->GetArrayLength(env, strArray);
    const char* args[arrayLength];

    int i;
    for(i = 0; i < arrayLength; i++){
        jstring jstr = (jstring)((*env)->GetObjectArrayElement(env, strArray, i));
        args[i] = (*env)->GetStringUTFChars(env, jstr, 0);
        //strcpy(args[i], arg);
        //env->ReleaseStringUTFChars(jstr, arg);
    }


    const char** argv = args;
    return  cmd_simulation(arrayLength, argv);  

}

After compilation with ffmpeg, you can simulate excuting ffmpeg commands like:

private void executeCommand(){
    String[] command = {"ffmpeg", "-i", "some video file name",};
    int result = test(command);     
}

Hope this helps!

EDIT: Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_WHOLE_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale libswresample libavfilter
LOCAL_MODULE    := VideoUtilLib
LOCAL_SRC_FILES := NativeVideoUtil.c ffmpeg.c ffmpeg_opt.c cmdutils.c ffmpeg_filter.c
LOCAL_LDLIBS := -lz -llog
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))

Replace NativeVideoUtil.c with your native file.

Sign up to request clarification or add additional context in comments.

5 Comments

awesome approach ! I will try your way ! I am away from my office, so I have to wait until tomorrow morning. Meanwhile can you tell me, do I have to rebuild ffmpeg for android after doing the modification ? Do I need to include any header file in my native code file ?
The header files you need to include are just <jni.h> and <stdio.h>. I will post my Android.mk in my answer.
I am getting this error: 08-14 05:30:11.729: W/dalvikvm(17973): PR_CAPBSET_DROP 0 failed: Invalid argument. Please make sure your kernel is compiled with file capabilities support enabled.
I compiled my android project directly with ffmpeg source code. So I didn't come across this problem. Maybe you can try compiling with ffmpeg source code.
can please give us ffmpeg source code which you have compiled?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.