【发布时间】:2015-01-15 04:46:35
【问题描述】:
cwac-camera 库具有在保存照片之前调用的事件挂钩:
@Override public void saveImage(PictureTransaction xact, byte[] image) {}
我只是忽略了这一点,还是没有接收器告诉我视频文件何时保存?
更多背景信息:结束视频的方法有两种。一种是调用
.stopRecording();
另一种方法是将记录器配置为最大持续时间/最大文件大小(在这种情况下,无需显式调用 stopRecording() 即可停止记录:
recorder.setMaxDuration()
在我看来,在这两种情况下,Android 都需要大约 100 到 200 毫秒来完成文件。由于我刚使用时视频文件经常损坏
mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
@Override public void onInfo(MediaRecorder mr, int what, int extra) {}
}
检测它何时完成或尝试在调用 stopRecording() 后立即读取它。我尝试使用 FileObserver 来检测媒体记录器何时真正关闭文件,效果很好。
我想讨论一下这个问题,如果有人有同样的经历,以及 cwac-camera 是否有办法检测记录的文件并发出信号。
--
我刚刚在 http://developer.android.com/reference/android/media/MediaRecorder.html#setMaxDuration(int)987654321@ 的 Android 文档中跳过了这个
“停止是异步发生的,无法保证在通知侦听器时记录器已经停止。”
这解释了为什么文件有时没有正确关闭,这隐含地意味着使用 FileObserver 可能是在文件写入后访问文件的唯一安全且有效的方法。
所以我们需要这样的东西来检测事件。
@Override protected File getVideoPath() {
File file = super.getVideoPath(); // assemble the video path
fileObserverPath = file.getAbsolutePath();
fileObserver = new FileObserver(fileObserverPath, FileObserver.CLOSE_WRITE) {
@Override public void onEvent(int event, String videoPath) {
System.out.println("**** CameraHost: write closed");
if (fileObserver != null) { // defensive
fileObserver.stopWatching();
fileObserver = null;
}
// process the file here
}
};
fileObserver.startWatching();
return file;
}
--
我继续将以下代码添加到我的 CameraHost 以获取时间:
@Override public void configureRecorderOutput(int cameraId, MediaRecorder recorder) {
System.out.println("**** CameraHost: configureRecorderOutput");
recorder.setMaxDuration(Constants.FRAMEPLAYER_MAX_RECORDING_LENGTH_PER_FRAME_MSEC);
recorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
@Override public void onInfo(MediaRecorder mr, int what, int extra) {
switch (what) {
case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED: {
System.out.println("**** CameraHost: MEDIA_RECORDER_INFO_MAX_DURATION_REACHED");
break;
}
}
}
});
super.configureRecorderOutput(cameraId, recorder);
}
时间安排:
11-20 07:33:28.974 32602-32602/cc.closeup.android I/System.out﹕ **** CameraHost: configureRecorderOutput
11-20 07:33:31.064 32602-32602/cc.closeup.android I/System.out﹕ **** CameraHost: MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
11-20 07:33:31.084 32602-32602/cc.closeup.android I/System.out﹕ **** CameraHost: MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
11-20 07:33:36.914 32602-32655/cc.closeup.android I/System.out﹕ **** CameraHost: write closed
11-20 07:33:36.914 32602-32655/cc.closeup.android I/System.out﹕ **** CameraHost: write closed
两件奇怪的事:
- MEDIA_RECORDER_INFO_MAX_DURATION_REACHED 已引发,但录制不会停止。与 Android 文档中的规定相反,我必须显式调用 stop。
- 即使 configureRecorderOutput 只引发了一次,我的侦听器也被调用了两次。我尝试了相同的外部 cwac 摄像头,那里的听众只被调用一次。
不确定我是否在某处出错或 cwac-camera 出现问题。
有人评论吗?
--
关于 2.,不管是什么,我的日志显示触发事件的媒体记录器是相同的,并且在 what=800 (MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) 之后不久,就会引发未记录的 what=536871912。第二次引发事件时,未记录的 what=268436456。
[来自华硕备忘录 7:]
11-20 09:41:25.748 3398-3398/cc.closeup.android I/System.out﹕ **** CameraHost: onInfo: mr = android.media.MediaRecorder@41c9da88, what = 800, extra 0
11-20 09:41:25.748 3398-3398/cc.closeup.android I/System.out﹕ **** CameraHost: MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
11-20 09:41:25.748 3398-3398/cc.closeup.android I/System.out﹕ **** CameraHost: onInfo: mr = android.media.MediaRecorder@41c9da88, what = 536871912, extra 0
11-20 09:41:25.778 3398-3398/cc.closeup.android I/System.out﹕ **** CameraHost: onInfo: mr = android.media.MediaRecorder@41c9da88, what = 800, extra 0
11-20 09:41:25.778 3398-3398/cc.closeup.android I/System.out﹕ **** CameraHost: MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
11-20 09:41:25.778 3398-3398/cc.closeup.android I/System.out﹕ **** CameraHost: onInfo: mr = android.media.MediaRecorder@41c9da88, what = 268436456, extra 0
我在另一台设备上运行了这个,MEDIA_RECORDER_INFO_MAX_DURATION_REACHED 事件也被引发了两次,但未记录的 what=?根本没有提出来。供应商具体实施?
[来自三星 Galaxy Note 2:]
11-20 09:46:42.711 25699-25699/cc.closeup.android I/System.out﹕ **** CameraHost: onInfo: mr = android.media.MediaRecorder@42831c30, what = 800, extra 0
11-20 09:46:42.711 25699-25699/cc.closeup.android I/System.out﹕ **** CameraHost: MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
11-20 09:46:42.776 25699-25699/cc.closeup.android I/System.out﹕ **** CameraHost: onInfo: mr = android.media.MediaRecorder@42831c30, what = 800, extra 0
11-20 09:46:42.776 25699-25699/cc.closeup.android I/System.out﹕ **** CameraHost: MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
我一直在发帖……
--
关于1.,录制实际上是停止的(录制的文件是一秒长),但FileObserver()显然只是在很久以后才调用,即在我显式调用cameraView.stop()之后。
我尝试在事件中传递的 MediaRecorder 上直接调用 stop(),它在 Android 中有效,但在 cwac 中无效。
--
关于 1.,我对此进行了更深入的研究,看起来视频文件在我明确调用 cameraView.stop() 之前一直保持写入 - 只有这样它才会被截断到一秒并关闭。
// startRecording() called here
11-20 11:29:49.072 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:49.072 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 32, videoPath = media0.mp4
11-20 11:29:49.082 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:49.082 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:49.082 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:49.082 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:49.082 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:49.082 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.132 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.132 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.132 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.132 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.132 4987-4987/cc.closeup.android I/System.out﹕ **** CameraHost: MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
11-20 11:29:51.142 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.142 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.142 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.142 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.142 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
(...)
11-20 11:29:51.182 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.182 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.182 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.192 4987-4987/cc.closeup.android I/System.out﹕ **** CameraHost: MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
11-20 11:29:51.192 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.192 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.192 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.192 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.192 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
(...)
11-20 11:29:51.252 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.262 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.262 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.262 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.262 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:51.262 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
// stopRecording() called here
11-20 11:29:52.492 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.492 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.492 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.492 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.572 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.572 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.572 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.572 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.572 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.572 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.572 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
(...)
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 2, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: FileObserver: onEvent: event = 8, videoPath = media0.mp4
11-20 11:29:52.582 4987-5167/cc.closeup.android I/System.out﹕ **** CameraHost: write closed: videoPath = media0.mp4
【问题讨论】:
标签: android video commonsware-cwac cwac-camera