2

I am trying to record video using OpenCV with some overlayed data. I have added OpenCV to my project and get camera preview successfully. While searching for how can I record video I came across to JavaCV. JavaCV has a sapmle activity called RecordActivity to demostrate video recording. It adds a CameraView dynamically with code and get camera frames and record them in onPreviewFrame method of the CameraView. You can see the full code here:

RecordAvtivity.java

What I want to do is record video in onCameraFrame metod of the CvCameraViewListener2 interface instead of onPreviewFrame metod of the PreviewCallback.

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

JavaCV record code block from RecordAvtivity.java

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 needs data as byte[] but I have Mat object. I need to cenvert between them efficiently.

How can I do that?

UPDATE:

I have used following solution to solve my initial problem

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();
        }
    }
}

but now I am getting following error:

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)

I have tried solution from below question but it didn't work:

JavaCV configuration in Android Studio

I have also tried both manual and gradle install for JavaCV but none of them worked.

I am using:

  • Android Studio 1.4
  • OpenCV 3.0
  • JavaCV 1.0
Community
  • 1
  • 1
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112

1 Answers1

0

add these lines to dependencies

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'

and add packagingOptions inside android {}

packagingOptions{}

and add these lines to 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'

It's working for me. hope it's helpful for you.

陳默司
  • 31
  • 2