2013-08-13 3 views
4

나는 bambuser 을 사용하여 android 용 ffmpeg를 성공적으로 만들었습니다. 이제 3gp에 mp4와 같은 샘플 변환기 응용 프로그램을 빌드해야합니다. 명령 줄 명령이 있다는 것을 알고 있습니다. ffmpeg -i video_origine.avi video_finale.mpg. 그러나 나는이 명령들을 프로그램 적으로 어떻게 실행해야할지 모른다.안드로이드에서 프로그래밍 방식으로 명령 줄 ffmpeg 명령을 실행하는 방법은 무엇입니까?

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와 컴파일 한 후, 당신이 좋아는 FFmpeg 명령을 Executing (실행 중) 시뮬레이션 할 수 있습니다 :이 도움이

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

희망을!

편집 : 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 : 잘못된 인수입니다. 커널이 파일 기능 지원을 사용하도록 컴파일되었는지 확인하십시오. –

관련 문제