Video recording to a circular buffer on Android
Asked Answered
W

1

12

I'm looking for the best way (if any...) to capture continuous video to a circular buffer on the SD card, allowing the user to capture events after they have happened.

The standard video recording API allows you to just write directly to a file, and when you reach the limit (set by the user, or the capacity of the SD card) you have to stop and restart the recording. This creates up to a 2 second long window where the recording is not running. This is what some existing apps like DailyRoads Voyager already do. To minimize the chance of missing something important you can set the splitting time to something long, like 10 minutes, but if an event occurs near the end of this timespan you are wasting space by storing the 9 minutes of nothing at the beginning.

So, my idea for now is as follows: I'll have a large file that will serve as the buffer. I'll use some code I've found to capture the frames and save them to the file myself, wrapping around at the end. When the user wants to keep some part, I'll mark it by pointers to the beginning and end in the buffer. The recording can continue as before, skipping over regions that are marked for retention.

After the recording is stopped, or maybe during that on a background thread (depending on phone/card speed) I'll copy out the marked region to another file and remove the overwrite protection.

Main question, if you don't care about the details above: I can't seem to find a way to convert the individual frames to a video file in the Android SDK. Is it possible? If not, are there any available libraries, maybe in native code, that can do this?

I don't really care about the big buffer of uncompressed frames, but the exported videos should be compressed in an Android-friendly format. But if there is a way to compress the buffer I would like to hear about it.

Thank you.

Width answered 23/1, 2012 at 15:26 Comment(0)
M
10

In Android's MediaRecorder there is two way to specify the output. One is a filename and another is a FileDescriptor.

Using static method fromSocket of ParcelFileDescriptor you can create an instance of ParcelFileDescriptor pointing to a socket. Then, call getFileDescriptor to get the FileDescriptor to be passed to the MediaRecorder.

Since you can get the encoded video from the socket (as if you were creating a local web server), you will be able to access individual frames of the video, although not so directly, because you will need to decode it first.

Muscadel answered 31/1, 2012 at 7:45 Comment(2)
Seems like a good way to get the encoded video stream, thanks. I'll have to try it out how it performs. But decoding the individual frames would use too much CPU, maybe wouldn't even be realtime (encoding+decoding at the same time) on some phones. So I think I'll just write the encoded stream to some circular file buffer, without the headers and so on. Then during export I'll try to patch the encoded frames together with some header and create a valid video file.Width
Can you provide some Demo Code ? It will be very helpful ! =)Doxology

© 2022 - 2024 — McMap. All rights reserved.