szakal
szakal

Reputation: 136

Running ffmpeg as library in android

I've got a simple task to do. I need to merge set of pictures into a video using ffmpeg working in android environment.

After over a week fighting with different tutorials and examples explaining how to run compile ffmpeg I have, let's say, middle success. I've finally compiled ffmpeg for android.

I followed this example: https://github.com/appunite/AndroidFFmpeg which worked best for me.

As a result of building ffmpeg a have following directory structure:

[Project]/jni/ffmpeg-build/armeabi-v7a/libffmpeg.so
[Project]/jni/ffmpeg-build/armeabi/libffmpeg.so
[Project]/jni/ffmpeg-build/mips/libffmpeg.so
[Project]/jni/ffmpeg-build/x86/libffmpeg.so

I also followed the ndk examples so I have running c code from java:

#include <string.h>
#include <jni.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>    
#include <android/log.h>    
#include <stdlib.h>
#include <stdbool.h>

bool initted = false;    
static JavaVM *sVm;

jstring Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv* env, jobject thiz) {

    char **argv;
    char *cmd;
    int argc;

//  cmd = "ffmpeg -version";
//  argv = parsedargs(cmd, &argc);
//  ffmpeg(argc, argv);

    return (*env)->NewStringUTF(env, "Hello from JNI !");

}

My question is how to run function from ffmpeg from my "hello-jni" c-file. I've read I need to write a wrapper over ffmpeg which my hello-jni is intended to be.

Here is my Android.mk which probably is importat part to achieve my goal, but honestly I don't understand some lines set in this file. Or simply I don't know how to make things work.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg-prebuilt
LOCAL_SRC_FILES := ffmpeg-build/$(TARGET_ARCH_ABI)/libffmpeg.so
LOCAL_EXPORT_C_INCLUDES := ffmpeg-build/$(TARGET_ARCH_ABI)/include
LOCAL_EXPORT_LDLIBS := ffmpeg-build/$(TARGET_ARCH_ABI)/libffmpeg.so
LOCAL_PRELINK_MODULE := true
include $(PREBUILT_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_ALLOW_UNDEFINED_SYMBOLS=true
LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ffmpeg-build/$(TARGET_ARCH_ABI)/include
LOCAL_SHARED_LIBRARY := ffmpeg-prebuilt
#LOCAL_CFLAGS += -g -Iffmpeg-prebuilt -Ihello-jni -Wno-deprecated-declarations 
#LOCAL_LDLIBS += -llog -lz -landroid ffmpeg-build/$(TARGET_ARCH_ABI)/libffmpeg.so 

include $(BUILD_SHARED_LIBRARY)

One more thing. I've found an example how to wrap ffmpeg's main function. It'd be the easiest way to use ffmpeg for me sinse I don't know ffmpeg's api and I hope it's possible to run ffmpeg this way: Can FFmpeg be used as a library, instead of a standalone program?

To sum up, I think my problems are due to completely lack of c/c++ knowledge at all, especially how to use run any function from .so library.

I hope someone can help me :).

Upvotes: 7

Views: 12904

Answers (1)

Robert Rowntree
Robert Rowntree

Reputation: 6289

https://github.com/halfninja/android-ffmpeg-x264/blob/master/Project/jni/videokit/uk_co_halfninja_videokit_Videokit.c

Look at the 'JNI_Call...' in the link above. That is how to call the wrapper for 'ffmpeg.main()' from android.

https://github.com/halfninja/android-ffmpeg-x264/blob/master/Project/jni/videokit/ffmpeg.c

use link above and find 'main()' at the very end. This is example of very slightly altered version of ffmpeg.c (logger altered for java/android ndk).

If you study these samples , you should get feeling for how to wrapper ffmpeg.main() in one of the other projects if you want to use it. The logger issue is moot at this point so the more modern [android-ffmpeg] projects on git can just make ffmpeg.c out of the box and use it with JNI. The only thing u may still have to change is the 'exit()' at the very end of main().

Upvotes: 5

Related Questions