How to programmatically execute ffmpeg command line commands in android?

I have successfully built ffmpeg for android using bambuser . Now I need to create an example converter application, for example mp4-3gp. I know there are command-line commands ffmpeg -i video_origine.avi video_finale.mpg . But I do not know how to execute these commands programmatically. 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 opens the file and extracts information about the codec. All I want is to convert an open file to the desired format. Any help, such as a piece of code or steps to follow, would be greatly appreciated.

Can the ffmpeg API serve my purpose? If there is an existing API, this will be more useful.

+4
source share
1 answer

I recently encountered a similar problem. My solution is to simulate a command line in a Java program.

First, 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 slight modification.

Then create your own 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 compiling with ffmpeg, you can simulate the excout of the ffmpeg command, for example:

 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.

+2
source

Source: https://habr.com/ru/post/1496736/


All Articles