0

I need to take a picture file and an audio file and create a video. I know that it's possible to do with the help of

Runtime.getRuntime().exec("ffmpeg -i image.jpeg -i audio.mp3 out.avi") 

but only for rooted devices, so I've tried to create JNI wrapper for main() from ffmpeg.c and call it from my Activity like here: http://demo860.blogspot.com/2010/07/android-ffmpeg-dynamic-module-jni.html

1.This code is in ffmpeg.c :

int m_argc = 0;
char *m_pargv [30];

int dynamic_ffpmeg_main (int argc, char **argv);
jint JNICALL Java_com_ccmedia_codec_ffmpeg_mod_1run ( JNIEnv *, jclass, jstring,     jstring );

jint JNICALL Java_com_ccmedia_codec_ffmpeg_mod_1run ( JNIEnv *env, jclass class, jstring pj1, jstring pj2)
{
    // as in http://demo860.blogspot.com/2010/07/android-ffmpeg-dynamic-module-jni.html
}

int dynamic_ffpmeg_main(int argc, char **argv)
{
// as in http://demo860.blogspot.com/2010/07/android-ffmpeg-dynamic-module-jni.html
}

int main(int argc, char **argv)
{
    dynamic_ffpmeg_main ( argc, argv );
    return 0;
}

2.This code is in my .java:

public class FFmpegCreator implements Runnable {

    static boolean m_bret = false;
static String m_szconfig = " -i /sdcard/file.mpg -vcodec mpeg4 aaa.mpg";

//public native String unimplementedStringFromJNI();

static {
    try {

        System.out.println("[AdDBCache] Module load try ffmpeg : "
                + System.getProperty("java.library.path"));

        // System.load("/sdcard/arm_and/bin/libffmpeg.so");

        System.loadLibrary("ffmpeg");

        System.out.println("[AdDBCache] Module load success");

    }

    catch (Exception e) {

        System.out.println("[AdDBCache] Module load err : "
                + System.getProperty("java.library.path"));

    }

}

private static synchronized final native int Java_com_ccmedia_codec_ffmpeg_mod_1run(String name, String sztoken);

public void set_config(String sz_config) {

    m_szconfig = sz_config;

}

public void run_core(String sz_file, String sz_token) {

    int n_stat;
    m_bret = false;
    n_stat = Java_com_ccmedia_codec_ffmpeg_mod_1run(m_szconfig, sz_token);
    m_bret = true;

}

public void run() {

    run_core("", "");

}
}

3.And this in my Activity:

FFmpegCreator f = new FFmpegCreator ();
new Thread(f).start();

But I have

E/AndroidRuntime(25682): java.lang.UnsatisfiedLinkError: Java_com_ccmedia_codec_ffmpeg_mod_1run .

And I can't understand why... FFmpeg build was successful... Could anyone help me, please? I'll really appreciate if you could help me. Thank you.

1 Answer 1

1

The problem is the naming of the native method Java_com_ccmedia_codec_ffmpeg_mod_1run on the Java side. You should just give it a normal method name, without all of the Java_package... parts. Then to match this to a C function you need to use the package and class that the method belongs. The most fool-proof way to do this is to update the Java side first:

public class FFmpegCreator implements Runnable {
    // ...

    private static synchronized final native int mod_1run(String name, String sztoken);

    //...
}

and then run javah on the class:

$ javah -o FFmpegCreator.h -classpath bin/classes com.yourpackage.FFmpegCreator

(replace bin/classes with the directory where your .class files are compiled, and com.yourpackage with the package that FFmpegCreator is within). If you look at the FFmpegCreator.h it generates it will include the correct signature for your native method.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you so much for the reply. I've done as you said. Gave a normal name, generated .h, but I still have the same error..
Did you update your ffmeg.c to use the signature that you see in the generated .h file? Using javah to generate the .h file is just to show you what the signature of this method needs to be on the C side, you still need to update the C code to use that signature.
Yes, I did.I got JNIEXPORT jint JNICALL java_com_appunite_ffmpeg_FFmpegCreator_mod_1run (JNIEnv *, jclass, jstring, jstring); and replaced in .c by jint JNICALL java_com_appunite_ffmpeg_FFmpegCreator_mod_1run (JNIEnv *, jclass, jstring, jstring)
Maybe it's because the function is declared in .c but not in .h. But as I remember it's possible to do in .c.
You should be able to do it in the .c file only, you'll only need a .h if you want to include it elsewhere in your C code.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.