2015-10-07 191 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' 

它爲我工作。希望這對你有所幫助。