2015-10-07 124 views
2

我正在尝试使用OpenCV来记录包含某些覆盖数据的视频。我已将OpenCV添加到我的项目并成功获取相机预览。在搜索我如何录制视频时,我碰到了JavaCVJavaCV有一个sapmle活动,称为RecordActivity去实现视频录制。它动态地添加CameraView代码并获取摄像机帧并将其记录在方法CameraView中。你可以看到完整的代码在这里:Android:FFmpegFrameRecorder(JavaCV)UnsatisfiedLinkError

RecordAvtivity.java

我想要做的就是在onCameraFrame梅托德的CvCameraViewListener2接口,而不是onPreviewFrame梅托德的PreviewCallback的录像。从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需要的数据作为byte[]但是我有Mat对象

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记录代码块。我需要有效地在它们之间进行切分。

我该怎么做?

UPDATE:

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

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
+0

http://answers.opencv.org/question/4761/mat-to-byte-array/ – Miki

+0

你在使用Proguard吗? –

+0

是的。但我试图禁用它,没有工作。 –

回答

0

将这些行添加到依赖性

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' 

它为我工作。希望这对你有所帮助。