2014-11-18 1 views
2

cwac-камера имеет крючки событий, которые вызываются перед тем фотография сохраняется:Обнаруживать, когда действительно был записан видеофайл? библиотека

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

, чтобы определить, когда она будет закончена, или попытаться повторно после того, как он остановил запись записи(). Я попытался использовать FileObserver, чтобы обнаружить, когда медиа-рекордер фактически закрывает файл, который работает хорошо.

Я хотел бы обсудить эту проблему, если у кого-то был такой же опыт, и если есть способ, как cwac-камера обнаруживает и сигнализирует записанный файл.

-

Я только что вышел из-за этого в Android документации здесь http://developer.android.com/reference/android/media/MediaRecorder.html#setMaxDuration(int)

«Остановка происходит асинхронно, нет никакой гарантии, что рекордер будет остановлен во время слушатель уведомлена»

Это объясняет, почему файл иногда не закрывается должным образом, и это подразумевает, что использование 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, я должен явно вызвать stop.
  2. Хотя configureRecorderOutput только один раз поднимается, мои слушатели вызывают дважды. Я попробовал ту же самую камеру вне камеры и там слушателей вызывают только один раз.

Не уверен, что я допустил ошибку где-то или что-то пошло не так в cwac-камере.

Никто не комментирует?

-

Относительно 2., что бы это, мой журнал показывает, что устройство записи, которое запускает событие такое же, и вскоре после того, что = 800 (MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) недокументированная, что = 536871912 приподнята. Во второй раз событие поднимает недокументированное значение = 268436456.

[от Asus Memo Pad 7:]

11-20 09:41:25.748 3398-3398/cc.closeup.android I/System.out﹕ **** CameraHost: onInfo: mr = [email protected], 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 = [email protected], what = 536871912, extra 0 

11-20 09:41:25.778 3398-3398/cc.closeup.android I/System.out﹕ **** CameraHost: onInfo: mr = [email protected], 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 = [email protected], what = 268436456, extra 0 

Я побежал это на другом устройстве, где MEDIA_RECORDER_INFO_MAX_DURATION_REACHED событие также поднял в два раза, но без документов какие =? вообще не поднимается. Реализация конкретного поставщика?

[от Samsung Galaxy Note 2:]

11-20 09:46:42.711 25699-25699/cc.closeup.android I/System.out﹕ **** CameraHost: onInfo: mr = [email protected], 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 = [email protected], 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., запись фактически остановлен (записанный файл один второй long), но FileObserver(), очевидно, вызывается гораздо позже, а именно после явного вызова метода cameraView.stop().

Я попытался вызвать stop() непосредственно на MediaRecorder, переданном в случае, которое работает в 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 

ответ

2

FileObserver может использоваться для обнаружения, когда файл был окончательно написан. Он может быть подключен в getVideoDirectory() замещают в 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 имеет ограничение, что он только работает точно, когда stopRecording() явно вызывается. Это слишком поздно, если запись завершена, потому что был достигнут размер или продолжительность заданных файлов (см. Также https://github.com/commonsguy/cwac-camera/issues/242).

Использование recorder.setOnInfoListener() не работает, поскольку оно может сообщать о завершении файла до того, как оно было фактически записано на диск.

Смежные вопросы