Android版のOpenCVで、ローカルのSDカード内にある動画ファイルを開いて編集したかったのですが、VideoCapture.javaにはネイティブメソッドの定義があるものの、Java側にコンストラクタが用意されていなかったので、こんな感じでMyVideoCapture.javaを用意して試してみました。
import org.opencv.highgui.VideoCapture; public class MyVideoCapture extends VideoCapture { protected final long nativeObj; public MyVideoCapture(String file) { nativeObj = n_VideoCapture(file); return; } private static native long n_VideoCapture(java.lang.String filename); }
結果としては、UnsatisfiedLinkErrorが発生しました。
09-16 23:34:51.932: W/dalvikvm(23911): No implementation found for native Lcom/example/android/opencv_test/utils/MyVideoCapture;.n_VideoCapture (Ljava/lang/String;)J 09-16 23:35:04.151: D/AndroidRuntime(23911): Shutting down VM 09-16 23:35:04.151: W/dalvikvm(23911): threadid=1: thread exiting with uncaught exception (group=0x40a251f8) 09-16 23:35:04.182: E/AndroidRuntime(23911): FATAL EXCEPTION: main 09-16 23:35:04.182: E/AndroidRuntime(23911): java.lang.UnsatisfiedLinkError: n_VideoCapture 09-16 23:35:04.182: E/AndroidRuntime(23911): at com.example.android.opencv_test.utils.MyVideoCapture.n_VideoCapture(Native Method) 09-16 23:35:04.182: E/AndroidRuntime(23911): at com.example.android.opencv_test.utils.MyVideoCapture.<init>(MyVideoCapture.java:10) 09-16 23:35:04.182: E/AndroidRuntime(23911): at com.example.android.opencv_test.MainActivity.onClick(MainActivity.java:92) 09-16 23:35:04.182: E/AndroidRuntime(23911): at android.view.View.performClick(View.java:3511) 09-16 23:35:04.182: E/AndroidRuntime(23911): at android.view.View$PerformClick.run(View.java:14105) 09-16 23:35:04.182: E/AndroidRuntime(23911): at android.os.Handler.handleCallback(Handler.java:605) 09-16 23:35:04.182: E/AndroidRuntime(23911): at android.os.Handler.dispatchMessage(Handler.java:92) 09-16 23:35:04.182: E/AndroidRuntime(23911): at android.os.Looper.loop(Looper.java:137) 09-16 23:35:04.182: E/AndroidRuntime(23911): at android.app.ActivityThread.main(ActivityThread.java:4424) 09-16 23:35:04.182: E/AndroidRuntime(23911): at java.lang.reflect.Method.invokeNative(Native Method) 09-16 23:35:04.182: E/AndroidRuntime(23911): at java.lang.reflect.Method.invoke(Method.java:511) 09-16 23:35:04.182: E/AndroidRuntime(23911): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 09-16 23:35:04.182: E/AndroidRuntime(23911): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 09-16 23:35:04.182: E/AndroidRuntime(23911): at dalvik.system.NativeStart.main(Native Method)
原因はファイルを開いてデコードするのに必要なnative側の機能を、Androidが持っていないため無効になっている、らしいです。
VideoCapture(String) interface – Google グループ
まぁ、キャプチャだけの用途ならMediaMetadataRetriever.getFrameAtTimeが使えるので、回避はできそうですが、先行きが不安です。
追記:
OpenCV 2.4.3ではAndroid 3.0以上に対してこの機能が有効になるそうです。OpenCV 2.4.3は2012年9月上旬にはリリースされるとのこと。
How to read a avi file from Android Opencv? – Google グループ
でもなぁ、最低でもAndroid 2.3はサポートしないとなぁ…