我已经使用bambuser为android成功构建了ffmpeg
.现在我必须建立一个像mp4到3gp的样本转换器应用程序.我知道有命令行命令ffmpeg -i video_origine.avi video_finale.mpg.但我不知道如何以编程方式执行这些命令.我有示例代码
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可用,则会更有帮助
解决方法:
最近我遇到了类似的问题.我的解决方案是在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);
}
希望这可以帮助!
编辑:
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替换为您的本机文件.