FFmpeg:调用 Runnable 类时出现 java.lang.UnsatisfiedLinkError

Posted

技术标签:

【中文标题】FFmpeg:调用 Runnable 类时出现 java.lang.UnsatisfiedLinkError【英文标题】:FFmpeg: java.lang.UnsatisfiedLinkError while calling Runnable class 【发布时间】:2013-03-12 21:29:07 【问题描述】:

我需要拍摄图片文件和音频文件并制作视频。 我知道可以在

的帮助下完成
Runtime.getRuntime().exec("ffmpeg -i image.jpeg -i audio.mp3 out.avi") 

但仅适用于有根设备,因此我尝试从 ffmpeg.c 为 main() 创建 JNI 包装器,并从我的 Activity 中调用它,如下所示:http://demo860.blogspot.com/2010/07/android-ffmpeg-dynamic-module-jni.html

1.这段代码在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.这段代码在我的.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.这在我的活动中:

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

但我有

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

我不明白为什么... FFmpeg 构建成功... 有人可以帮我吗?如果您能帮助我,我将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

问题是Java端的native方法Java_com_ccmedia_codec_ffmpeg_mod_1run的命名。您应该只给它一个普通的方法名称,而不是所有 Java_package... 部分。然后要将其与 C 函数匹配,您需要使用该方法所属的包和类。最简单的做法是先更新Java端:

public class FFmpegCreator implements Runnable 
    // ...

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

    //...

然后在类上运行javah:

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

(将bin/classes 替换为编译.class 文件的目录,将com.yourpackage 替换为FFmpegCreator 所在的包)。如果您查看它生成的FFmpegCreator.h,它将包含您本机方法的正确签名。

【讨论】:

非常感谢您的回复。我已经按照你说的做了。给了一个正常的名字,生成了.h,但我仍然有同样的错误.. 您是否更新了您的ffmeg.c 以使用您在生成的.h 文件中看到的签名?使用javah生成.h文件只是为了告诉你这个方法的签名需要在C端是什么,你仍然需要更新C代码才能使用那个签名。 是的,我做到了。我得到了 JNIEXPORT jint JNICALL java_com_appunite_ffmpeg_FFmpegCreator_mod_1run (JNIEnv *, jclass, jstring, jstring);并在 .c 中替换为 jint JNICALL java_com_appunite_ffmpeg_FFmpegCreator_mod_1run (JNIEnv *, jclass, jstring, jstring) 可能是因为函数是在 .c 中声明的,而不是在 .h 中声明的。但我记得在 .c. 中是可以做到的。 您应该只能在 .c 文件中执行此操作,如果您想在 C 代码的其他位置包含它,则只需要一个 .h。

以上是关于FFmpeg:调用 Runnable 类时出现 java.lang.UnsatisfiedLinkError的主要内容,如果未能解决你的问题,请参考以下文章

添加水印时出现FFmpeg错误:未覆盖 - 退出

在配置 ffmpeg 时出现错误“未找到 x264”

将FFmpeg作为php中的进程运行时出现超时错误

调用类方法时出现“调用未定义函数”错误

使用 += 但未附加列表时出现 UnboundLocalError [重复]

从另一个类调用函数时出现致命错误