【问题标题】:Android : FFmpegFrameRecorder (JavaCV) UnsatisfiedLinkErrorAndroid : FFmpegFrameRecorder (JavaCV) UnsatisfiedLinkError
【发布时间】:2016-01-04 11:38:27
【问题描述】:

我正在尝试使用带有一些叠加数据的 OpenCV 录制视频。我已将OpenCV 添加到我的项目中并成功获得相机预览。在搜索如何录制视频时,我遇到了JavaCVJavaCV 有一个名为RecordActivity 的样本活动来演示视频录制。它使用代码动态添加CameraView,并获取相机帧并将它们记录在CameraViewonPreviewFrame 方法中。你可以在这里看到完整的代码:

RecordAvtivity.java

我想做的是在CvCameraViewListener2接口的onCameraFrame方法而不是PreviewCallbackonPreviewFrame方法中录制视频。

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    final Mat rgba = inputFrame.rgba();
    Core.flip(rgba, rgba, 1);
    // Overlay some text and record video here.
    return rgba;
}

RecordAvtivity.java 中的 JavaCV 记录代码块

public void onPreviewFrame(byte[] data, Camera camera) {

    if (audioRecord == null || audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
        startTime = System.currentTimeMillis();
        return;
    }

    int i = imagesIndex++ % images.length;
    Frame yuvImage = images[i];
    timestamps[i] = 1000 * (System.currentTimeMillis() - startTime);

    /* get video data */
    if (yuvImage != null && recording) {
        ((ByteBuffer) yuvImage.image[0].position(0)).put(data);

        try {
            Log.v(TAG, "Writing Frame");
            long t = 1000 * (System.currentTimeMillis() - startTime);

            if (t > recorder.getTimestamp()) {
                recorder.setTimestamp(t);
            }

            recorder.record(yuvImage);
        } catch (FFmpegFrameRecorder.Exception e) {
            Log.v(TAG, e.getMessage());
            e.printStackTrace();
        }
    }
}

JavaCV 需要 byte[] 的数据,但我有 Mat 对象。我需要有效地在它们之间进行转换。

我该怎么做?

更新:

我使用以下解决方案来解决我最初的问题

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    final Mat rgba = inputFrame.rgba();
    Core.flip(rgba, rgba, 1);

    if (data == null) {
        data = new byte[(int)rgba.total() * rgba.channels()];
    }

    rgba.get(0,0, data);
    record(data);
    return rgba;
}

public void record(byte[] data) {

    if (audioRecord == null || audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
        startTime = System.currentTimeMillis();
        return;
    }

    int i = imagesIndex++ % images.length;
    Frame yuvImage = images[i];
    timestamps[i] = 1000 * (System.currentTimeMillis() - startTime);

    /* get video data */
    if (yuvImage != null && recording) {
        ((ByteBuffer) yuvImage.image[0].position(0)).put(data);

        try {
            Log.v(TAG, "Writing Frame");
            long t = 1000 * (System.currentTimeMillis() - startTime);

            if (t > recorder.getTimestamp()) {
                recorder.setTimestamp(t);
            }

            recorder.record(yuvImage);
        } catch (FFmpegFrameRecorder.Exception e) {
            Log.v(TAG, e.getMessage());
            e.printStackTrace();
        }
    }
}

但现在我收到以下错误:

FATAL EXCEPTION: main
E/AndroidRuntime: Process: com.yceo.anlatbana, PID: 17622
E/AndroidRuntime: java.lang.UnsatisfiedLinkError: org.bytedeco.javacpp.avutil
E/AndroidRuntime:     at java.lang.Class.classForName(Native Method)
E/AndroidRuntime:     at java.lang.Class.forName(Class.java:309)
E/AndroidRuntime:     at org.bytedeco.javacpp.Loader.load(Loader.java:390)
E/AndroidRuntime:     at org.bytedeco.javacpp.Loader.load(Loader.java:358)
E/AndroidRuntime:     at org.bytedeco.javacpp.avcodec$AVPacket.<clinit>(avcodec.java:1407)
E/AndroidRuntime:     at org.bytedeco.javacv.FFmpegFrameRecorder.<init>(FFmpegFrameRecorder.java:149)
E/AndroidRuntime:     at com.yceo.anlatbana.GameFragment.initRecorder(GameFragment.java:267)
E/AndroidRuntime:     at com.yceo.anlatbana.GameFragment.onCreate(GameFragment.java:98)
E/AndroidRuntime:     at android.support.v4.app.Fragment.performCreate(Fragment.java:1939)
E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:988)
E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1207)
E/AndroidRuntime:     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1572)
E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:493)
E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5310)
E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

我尝试了以下问题的解决方案,但没有奏效:

JavaCV configuration in Android Studio

我也尝试了 JavaCV 的手动安装和 gradle 安装,但都没有成功。

我正在使用:

  • Android Studio 1.4
  • OpenCV 3.0
  • JavaCV 1.0

【问题讨论】:

标签: android opencv ffmpeg javacv


【解决方案1】:

将这些行添加到依赖项

compile 'org.bytedeco.javacpp-presets:opencv:3.0.0-1.1:android-arm'
compile 'org.bytedeco.javacpp-presets:ffmpeg:2.8.1-1.1:android-arm'

并在 android {} 中添加 PackagingOptions

packagingOptions{}

并将这些行添加到 PackagingOptions

exclude 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.properties'
exclude 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.properties'
exclude 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.xml'
exclude 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.xml'

它对我有用。希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    相关资源
    最近更新 更多