检测何时视频文件已经确实写的? [英] Detect when video file has been really written?

查看:609
本文介绍了检测何时视频文件已经确实写的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在CWAC相机库有事件挂钩照片保存之前被称为:

  @覆盖公共无效saveImage(PictureTransaction XACT,字节[]图像){}

有我只是忽略了这或者是有没有下沉,告诉我,当视频文件已经保存?

一些更多的背景信息:有两种方式来结束录像。其一是通过调用

  .sto precording();

另一种是通过配置的最大持续时间/最大文件大小的记录(在这种情况下记录,但不显式调用停下来STO precording():

  recorder.setMaxDuration()

在这两种情况下,因为它看起来我,机器人需要约100至200毫秒来完成该文件。由于视频文件通常被损坏时,我只是用

  mediaRecorder.setOnInfoListener(新MediaRecorder.OnInfoListener(){
        @覆盖公共无效onInfo(MediaRecorder先生,诠释了什么,整型附加){}
}

当它完成检测或尝试调用STO precording后立即阅读它()。我试着用FileObserver当媒体录像机实际上关闭文件,效果很好检测。

我想讨论这个问题,如果有人有过同样的经历,如果有一种方法CWAC相机如何检测和信号录制的文件。

-

我刚刚跨过这个Android文档在这里的http://developer.android.com/reference/android/media/MediaRecorder.html#setMaxDuration(int)

停止异步发生,也不能保证该记录将被监听器通知时已经停止。

这解释了为什么有时文件没有正确关闭,它含蓄地意味着使用FileObserver可能是它已被写入后访问该文件的唯一安全的工作方式。

所以,我们需要这样的事情来检测该事件。

  @覆盖保护文件getVideoPath(){
    文件fil​​e = super.getVideoPath(); //组装视频路径
    fileObserverPath = file.getAbsolutePath();    fileObserver =新FileObserver(fileObserverPath,FileObserver.CLOSE_WRITE){
        @覆盖公共无效的onEvent(INT事件,弦乐将videoPath){            的System.out.println(**** CameraHost:写封闭);            如果(fileObserver!= NULL){//防守
                fileObserver.stopWatching();
                fileObserver = NULL;
            }            //过程中的文件在这里
        }
    };
    fileObserver.startWatching();    返回文件;
}

-

我说干就干,增加了以下code到我的CameraHost得到时序:

  @覆盖公共无效configureRecorderOutput(INT cameraId,MediaRecorder录像机){    的System.out.println(**** CameraHost:configureRecorderOutput);    recorder.setMaxDuration(Constants.FRAMEPLAYER_MAX_RECORDING_LENGTH_PER_FRAME_MSEC);
    recorder.setOnInfoListener(新MediaRecorder.OnInfoListener(){
        @覆盖公共无效onInfo(MediaRecorder先生,诠释了什么,整型附加){
            开关(什么){
                案例MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:{                    的System.out.println(**** CameraHost:MEDIA_RECORDER_INFO_MAX_DURATION_REACHED);                    打破;
                }
            }
        }
    });    super.configureRecorderOutput(cameraId,录像机);
}

时序:

  7月11日至20日:33:28.974 32602-32602 / cc.closeup.android I / System.out的:**** CameraHost:configureRecorderOutput
7月11日至20日:33:31.064 32602-32602 / cc.closeup.android I / System.out的:**** CameraHost:MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
7月11日至20日:33:31.084 32602-32602 / cc.closeup.android I / System.out的:**** CameraHost:MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
7月11日至20日:33:36.914 32602-32655 / cc.closeup.android I / System.out的:**** CameraHost:写关闭
7月11日至20日:33:36.914 32602-32655 / cc.closeup.android I / System.out的:**** CameraHost:写关闭

两件事情有蹊跷:


  1. MEDIA_RECORDER_INFO_MAX_DURATION_REACHED升高,但拍摄不会停止。相反的是Android的文件中规定,我必须显式调用停止。

  2. 尽管configureRecorderOutput只提出一次,我的听众被称为两次。我想同样的外面CWAC相机和有听众只调用一次。

不知道如果我做了什么地方错或不顺心的事在CWAC摄像头。

任何人有评论?

-

关于2,不​​管它是什么,我的日志显示,媒体录像机,触发事件是一样的,以后有什么= 800(MEDIA_RECORDER_INFO_MAX_DURATION_REACHED)短无证什么= 536871912升高。该事件引发的无证第二次什么= 268436456。

[华硕记事簿7:]

  9月11日至二十○日:41:25.748 3398-3398 / cc.closeup.android I / System.out的:**** CameraHost:onInfo:MR = android.media.MediaRecorder @ 41c9da88,什么= 800,额外的0
9月11日至20日:41:25.748 3398-3398 / cc.closeup.android I / System.out的:**** CameraHost:MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
9月11日至20日:41:25.748 3398-3398 / cc.closeup.android I / System.out的:**** CameraHost:onInfo:MR = android.media.MediaRecorder@41c9da88,什么= 536871912,额外09月11日至20日:41:25.778 3398-3398 / cc.closeup.android I / System.out的:**** CameraHost:onInfo:MR = android.media.MediaRecorder@41c9da88,什么= 800,额外的0
9月11日至20日:41:25.778 3398-3398 / cc.closeup.android I / System.out的:**** CameraHost:MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
9月11日至20日:41:25.778 3398-3398 / cc.closeup.android I / System.out的:**** CameraHost:onInfo:MR = android.media.MediaRecorder@41c9da88,什么= 268436456,额外0

我跑这另一台设备,其中MEDIA_RECORDER_INFO_MAX_DURATION_REACHED事件也两次上调,但无证=什么?在一切都没有提出。供应商的具体实现?

[从三星Galaxy Note 2:]

  9月11日至二十○日:46:42.711 25699-25699 / cc.closeup.android I / System.out的:**** CameraHost:onInfo:MR = android.media.MediaRecorder @ 42831c30,什么= 800,额外的0
9月11日至20日:46:42.711 25699-25699 / cc.closeup.android I / System.out的:**** CameraHost:MEDIA_RECORDER_INFO_MAX_DURATION_REACHED9月11日至20日:46:42.776 25699-25699 / cc.closeup.android I / System.out的:**** CameraHost:onInfo:MR = android.media.MediaRecorder@42831c30,什么= 800,额外的0
9月11日至20日:46:42.776 25699-25699 / cc.closeup.android I / System.out的:**** CameraHost:MEDIA_RECORDER_INFO_MAX_DURATION_REACHED

我一直张贴...

-

关于1,记录实际上是停止(录音文件为一秒长),但FileObserver()显然是只叫很久以后,也就是在我明确地调用cameraView.stop()。

我试着打的stop()直接在MediaRecorder事件,这在Android中,但不是在工作CWAC过去了。

-

对于1,我挖这个进一步,它看起来像视频文件,保持书面直到我明确调用cameraView.stop() - 才把它是截断到一秒钟,闭合

  //这里叫做的startRecording()11月11日至20日:29:49.072 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:49.072 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 32,将videoPath = media0.mp4
11月11日至20日:29:49.082 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:49.082 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:49.082 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:49.082 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:49.082 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:49.082 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.132 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.132 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.132 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.132 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp411月11日至20日:29:51.132 4987-4987 / cc.closeup.android I / System.out的:**** CameraHost:MEDIA_RECORDER_INFO_MAX_DURATION_REACHED11月11日至20日:29:51.142 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.142 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.142 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.142 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.142 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
(......)
11月11日至20日:29:51.182 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.182 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.182 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp411月11日至20日:29:51.192 4987-4987 / cc.closeup.android I / System.out的:**** CameraHost:MEDIA_RECORDER_INFO_MAX_DURATION_REACHED11月11日至20日:29:51.192 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.192 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.192 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.192 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.192 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
(......)
11月11日至20日:29:51.252 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.262 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.262 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.262 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.262 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:51.262 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4这里所说// STO precording()11月11日至20日:29:52.492 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.492 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.492 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.492 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.572 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.572 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.572 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.572 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.572 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.572 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.572 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
(......)
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 2,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:FileObserver:的onEvent:事件= 8,将videoPath = media0.mp4
11月11日至20日:29:52.582 4987-5167 / cc.closeup.android I / System.out的:**** CameraHost:写封闭:将videoPath = media0.mp4


解决方案

FileObserver可以用来当一个文件被最终写入检测。它可以挂接到getVideoDirectory()覆盖在CameraHost:

  @覆盖保护文件getVideoDirectory(){
    fileObserver =新FileObserver(videoDirectory.getAbsolutePath(),FileObserver.CLOSE_WRITE){
        @覆盖公共无效的onEvent(INT事件,弦乐将videoPath){
            的System.out.println(**** CameraHost:FileObserver:的onEvent:事件=+事件+,将videoPath =+将videoPath);            如果(fileObserver = NULL&放大器;!&安培;将videoPath = NULL&放大器;!&安培;事件== FileObserver.CLOSE_WRITE){//不能正确处理目录
                的System.out.println(**** CameraHost:写封闭:将videoPath =+将videoPath);                // fileObserver.stopWatching(); // TODO这需要关闭的地方
                // fileObserver = NULL;                raiseVideo(将videoPath);
            }
        }
    };
    fileObserver.startWatching();    返回videoDirectory;
}

FileObserver有它只能准确地当STO precording()显式调用的限制。它被升高太晚如果记录被终止,因为$ P $对定义文件的大小或持续时间已经达到(也见 https://github.com/commonsguy/cwac-camera/issues/242 )。

使用recorder.setOnInfoListener()不工作,因为之前已实际写入磁盘可能会报告一个文件的定稿。

The cwac-camera library has event hooks that are called before a photo is saved:

@Override public void saveImage(PictureTransaction xact, byte[] image) {}

Have I just overlooked this or is there no sink which tells me when a video file has been saved?

Some more background info: There are two ways to end a video. One is by calling

.stopRecording();

the other is by configuring the recorder for a max duration/max filesize (in which case recording stops without the explicit call to stopRecording():

recorder.setMaxDuration()

In both cases, as it looks to me, Android needs about 100 to 200 msec to finalize the file. As the video file is often corrupted when I just use

mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
        @Override public void onInfo(MediaRecorder mr, int what, int extra) {}
}

to detect when it is finished or try reading it immediately after the call to stopRecording(). I tried using FileObserver to detect when media recorder actually closes the file, which works well.

I'd like to discuss this issue, if anybody has had the same experience, and if there is a way how cwac-camera detects and signals a recorded file.

--

I just stepped over this in Android documentation here http://developer.android.com/reference/android/media/MediaRecorder.html#setMaxDuration(int)

"Stopping happens asynchronously, there is no guarantee that the recorder will have stopped by the time the listener is notified."

This explains why the file sometimes isn't properly closed and it implicitly means that using FileObserver probably is the only safe and working way to access the file after it has been written.

So we need something like this to detect the event.

@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;
}

--

I went ahead and added the following code to my CameraHost to get the timings:

@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);
}

Timings:

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

Two things that are strange:

  1. MEDIA_RECORDER_INFO_MAX_DURATION_REACHED is raised, but the recording does not stop. Contrary to what is specified in the Android documentation, I must explicitly call stop.
  2. Even though configureRecorderOutput is only raised once, my listeners are called twice. I tried the same outside cwac camera and there listeners are only called once.

Not sure if I made a mistake somewhere or something goes wrong in cwac-camera.

Anybody there to comment?

--

Regarding 2., whatever that is, my log reveals that the media recorder which fires the event is the same, and short after what=800 (MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) an undocumented what=536871912 is raised. The second time the event is raised the undocumented what=268436456.

[from Asus 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

I ran this on another device, where the MEDIA_RECORDER_INFO_MAX_DURATION_REACHED event is also raised twice, but the undocumented what=? is not raised at all. Vendor specific implementation?

[from Samsung 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

I keep posting...

--

Regarding 1., recording is actually stopped (the recorded file is one second long), but FileObserver() is obviously only called much later, namely after I explicitly call cameraView.stop().

I tried to call stop() directly on the MediaRecorder passed in the event, which works in Android but not in cwac.

--

Regarding 1., I digged into this further and it looks like the video file is kept written until I explicitly call cameraView.stop() - only then is it truncated to one second and closed.

// 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 can be used to detect when a file has been finally written. It can be hooked into the getVideoDirectory() override in CameraHost:

@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 has the limitation that it only works accurately when stopRecording() is explicitly called. It is raised too late if the recording is terminated because a pre-defined files size or duration has been reached (see also https://github.com/commonsguy/cwac-camera/issues/242 ).

Using recorder.setOnInfoListener() does not work, because it may report finalization of a file before it has been actually written to disk.

这篇关于检测何时视频文件已经确实写的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆