gpt4 book ai didi

android - 检测视频文件何时真正写入?

转载 作者:搜寻专家 更新时间:2023-11-01 08:47:14 25 4
gpt4 key购买 nike

cwac-camera 库具有在保存照片之前调用的事件 Hook :

@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) 的 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

有两点很奇怪:

  1. MEDIA_RECORDER_INFO_MAX_DURATION_REACHED 已启动,但录制不会停止。与 Android 文档中指定的相反,我必须明确调用停止。
  2. 即使只引发一次 configureRecorderOutput,我的监听器也被调用了两次。我尝试了同样的外部 cwac 摄像头,那里的听众只被调用一次。

不确定是我在某处犯了错误还是 cwac-camera 出了问题。

有人要评论吗?

--

关于 2.,无论那是什么,我的日志显示触发事件的媒体记录器是相同的,并且在 what=800 (MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) 之后不久,一个未记录的 what=536871912 被引发。第二次引发事件时未记录的 what=268436456。

[来自华硕 Memo Pad 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

最佳答案

FileObserver 可用于检测文件何时最终写入。它可以挂接到 CameraHost 中的 getVideoDirectory() 覆盖中:

@Override protected File getVideoDirectory() {
fileObserver = new FileObserver(videoDirectory.getAbsolutePath(), FileObserver.CLOSE_WRITE) {
@Override public void onEvent(int event, String videoPath) {
System.out.println("**** CameraHost: FileObserver: onEvent: event = " + event + ", videoPath = " + videoPath);

if (fileObserver != null && videoPath != null && event == FileObserver.CLOSE_WRITE) { // do not process directory
System.out.println("**** CameraHost: write closed: videoPath = " + videoPath);

// fileObserver.stopWatching(); // TODO this needs to be closed somewhere
// fileObserver = null;

raiseVideo(videoPath);
}
}
};
fileObserver.startWatching();

return videoDirectory;
}

FileObserver 的局限性在于它只有在显式调用 stopRecording() 时才能准确工作。如果由于达到预定义的文件大小或持续时间而终止录制,则为时已晚(另请参见 https://github.com/commonsguy/cwac-camera/issues/242 )。

使用 recorder.setOnInfoListener() 不起作用,因为它可能会在文件实际写入磁盘之前报告文件已完成。

关于android - 检测视频文件何时真正写入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26986821/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com