2013-08-13 5 views
4

Я успешно построил ffmpeg для android, используя bambuser . Теперь мне нужно создать примерное приложение-конвертер, например mp4-3gp. Я знаю, что есть команды командной строки ffmpeg -i video_origine.avi video_finale.mpg. Но я не знаю, как выполнять эти команды программно. У меня есть пример кода, напримерКак выполнить командные команды ffmpeg программно в android?

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; 
} 

Этот код открывает файл и извлекает информацию о кодеке. Все, что я хочу, это то, что для преобразования открытого файла в желаемый формат. Любые виды помощи, такие как фрагмент кода или шаги, которые следует выполнить, будут высоко оценены.

Может ли ffmpeg API служить моей цели? Если имеется существующий API, это будет более полезно

ответ

2

Недавно я столкнулся с подобной проблемой. Мое решение - имитировать командную строку в программе Java.

Во-первых, добавить функцию в файл «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; 
} 

На самом деле эта функция просто копия основной функции с небольшой модификацией.

Затем создайте родную функцию:

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); 

} 

После компиляции с FFmpeg, можно имитировать excuting команды FFmpeg как:

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

Надеется, что это помогает!

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)) 

Заменить NativeVideoUtil.c с родным файлом.

+0

удивительный подход! Я попробую свой путь! Я вдали от своего офиса, поэтому я должен подождать до завтрашнего утра. Между тем, можете ли вы мне сказать, мне нужно перестроить ffmpeg для андроида после выполнения модификации? Нужно ли включать заголовочный файл в свой собственный файл кода? –

+0

Файлы заголовков, которые необходимо включить, - это только и . Я отправлю свой Android.mk в свой ответ. – shhp

+0

Я получаю эту ошибку: 08-14 05: 30: 11.729: W/dalvikvm (17973): PR_CAPBSET_DROP 0 failed: Недопустимый аргумент. Убедитесь, что ваше ядро ​​скомпилировано с поддержкой поддержки файлов. –

Смежные вопросы