VideoCapture lifecycle aware video recording

77 views
Skip to first unread message
Assigned to leoh...@google.com by wuj...@google.com

Javier Gerardo Martinez Salomon

unread,
Jun 7, 2024, 8:09:39 PMJun 7
to Android CameraX Discussion Group
Hi CameraX devs,

First of all, thank you very much for this amazing library I enjoy working with, it's great to see constant improvements and updates, please keep it going.

I'd like to discuss a UseCase related to the use of the VideoCapture feature, I'm currently doing a POC and using CameraX 1.3.3 where I want to start the recording of a video as soon as the preview is available and stop the recording when the preview is gone for that, I'm using a lifecycle aware component that initializes the camera and binds the usecases in the ON_RESUME event and tears down the camera, unbinds the usecases and finishes the recording in the ON_PAUSE event, I only start the recording after I've called bindUseCases().

In a normal situation this works pretty well and the sequence goes as follows:
  1. ON_RESUME -> build and bind the usecases with bindUseCases
  2. Start the video recording
  3. I get the VideoRecordEvent.Start in the observer
  4. After some time when the video is done I finish the recording with ActiveRecording.stop() and unbindAll()
  5. I get the VideoRecordEvent.Finalized in the observer and the video is done
When there is a configuration change such as the phone rotation while recording, I'd like to stop and discard the recording in the ON_PAUSE method and start a new one in the ON_RESUME method, however, I found the following sequence:
  1. ON_RESUME -> build and bind the usecases with bindUseCases
  2. Start the video recording
  3. I get the VideoRecordEvent.Start in the observer
  4. Phone rotates and I get the ON_PAUSE event and call ActiveRecording.stop() and unbindAll()
  5. ON_RESUME -> build and bind the usecases with bindUseCases
  6. Start the video recording
  7. I get the VideoRecordEvent.Start in the observer
  8. I get the VideoRecordEvent.Finalized in the observer right after which finished the activeRecording.
So far the only thing that has worked for me is to place an arbitrary delay in the ActiveRecording.start() method so that the VideoRecordEvent.Finalized arrives before I start the new recording, however, I feel that there should be a better way to handle this situation, is there anything specific to the lifecycle of the recording that I'm missing? do you have any advise on how to achieve the desired functionality?

Please find attached a logcat which demonstrates the order of the VideoRecordEvent and lifecycle events, also there's a sample code attached with relevant portions such as the configuration of the VideoCapture usecase, the start and stop methods as well as the overall lifecycle logic to start/stop the camera and recordings.

Any help would be appreciated, thanks!
samsung-SM-G950U1-Android-9_2024-06-07_162729.logcat
sample_code.txt

Leo Huang

unread,
Jun 11, 2024, 4:23:10 PMJun 11
to Android CameraX Discussion Group, javiermart...@gmail.com
Hi 
Thanks for the question. From the log and sample code, it looks like the Finalize event is from the previous stopped recording. The next recording is actually running normally.

You can try to create a new VideoRecordEvent listener for every recording instead of reusing it.
i.e. 
Don't reuse this listener instance, create a new one to start another recording.
```
// video events listener
    private val recordingEventsListener =
        Consumer<VideoRecordEvent> { event ->
```
irVidRecordEvent> { event ->ventsListene
javiermart...@gmail.com 在 2024年6月8日 星期六上午8:09:39 [UTC+8] 的信中寫道:

Javier Gerardo Martinez Salomon

unread,
Jun 11, 2024, 6:16:52 PMJun 11
to Android CameraX Discussion Group, leoh...@google.com, Javier Gerardo Martinez Salomon
Ah, I understand and I was able to verify what you suggest based on the hashcode of the observer, indeed the Finalized state that I see after starting the video recording belongs to the "old" video recording, however, is there a recommended best practice to discard the events from an "inactive" VideoRecordEvent listener? In my case, I'd like to identify that the Finalized event belongs to an active recording and not to one that's shutting down.

As a follow-up question. Is there any negative side effect of having a VideoRecordEvent that is "shutting down" while there's a new instance to track the new(and active) recording?

Thanks in Advance

Javier Gerardo Martinez Salomon

unread,
Jun 11, 2024, 6:26:37 PMJun 11
to Android CameraX Discussion Group, Javier Gerardo Martinez Salomon, leoh...@google.com

Is there a way for example, to remove the observer from the current recording session?

Leo Huang

unread,
Jun 11, 2024, 11:09:37 PMJun 11
to Android CameraX Discussion Group, javiermart...@gmail.com, Leo Huang
> is there a recommended best practice to discard the events from an "inactive" VideoRecordEvent listener? In my case, I'd like to identify that the Finalized event belongs to an active recording and not to one that's shutting down.
While it's generally best to create a new listener for each recording, if you must use a single listener, you can identify the correct recording using VideoRecordEvent.getOutputOption(). Compare this with the OutputOptions you provided when starting the recording. If your OutputOptions remain consistent, this method won't be reliable.


>  Is there any negative side effect of having a VideoRecordEvent that is "shutting down" while there's a new instance to track the new(and active) recording?
The main concern with multiple recordings is limited device resources. If your device has enough codec resources, the second recording should work fine. If resources are scarce, the second recording may fail to start, resulting in a Finalize event with an error code. CameraX will actually attempt to retry a bit before giving up.


> Is there a way for example, to remove the observer from the current recording session?
Currently, the CameraX API doesn't provide a direct way to remove an observer from a recording session.
Here's a workaround: Create your own class that extends Consumer<VideoRecordEvent>. In this class, you can add logic to ignore or discard events once you've stopped the recording.

javiermart...@gmail.com 在 2024年6月12日 星期三清晨6:26:37 [UTC+8] 的信中寫道:

Javier Gerardo Martinez Salomon

unread,
Jun 14, 2024, 8:00:29 PMJun 14
to Android CameraX Discussion Group, leoh...@google.com, Javier Gerardo Martinez Salomon
Thanks for your answer,

Understanding how the observers remain active while shutting down the video recording within the CameraX library was very valuable, and indeed subclassing the Consumer<VideoRecordEvent> gives me enough flexibility to discard unwanted events after "unsubscribing" myself, it would be nice in the future to have a way to shutdown and release everything from a recording so that we don't have the possibility of multiple recordings taking resources from a device.
Reply all
Reply to author
Forward
0 new messages