【发布时间】:2016-01-04 11:38:27
【问题描述】:
我正在尝试使用带有一些叠加数据的 OpenCV 录制视频。我已将OpenCV 添加到我的项目中并成功获得相机预览。在搜索如何录制视频时,我遇到了JavaCV。 JavaCV 有一个名为RecordActivity 的样本活动来演示视频录制。它使用代码动态添加CameraView,并获取相机帧并将它们记录在CameraView 的onPreviewFrame 方法中。你可以在这里看到完整的代码:
我想做的是在CvCameraViewListener2接口的onCameraFrame方法而不是PreviewCallback的onPreviewFrame方法中录制视频。
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
【问题讨论】:
-
你在使用 Proguard 吗?
-
是的。但是我试过禁用它,没有用。
-
@EdsonMenegatti 我在 build gradle 中有 minifyEnabled false
-
您能粘贴添加 javacv 的编译调用吗?
标签: android opencv ffmpeg javacv