Search code examples
androidvideoffmpegandroid-mediacodecmediarecorder

Android - Choosing between MediaRecorder, MediaCodec and Ffmpeg


I am working on a video recording and sharing application for Android. The specifications of the app are as follows:-

  • Recording a 10 second (maximum) video from inside the app (not using the device's camera app)
  • No further editing on the video
  • Storing the video in a Firebase Cloud Storage (GCS) bucket
  • Downloading and playing of the said video by other users

From the research, I did on SO and others sources for this, I have found the following (please correct me if I am wrong):-

The three options and their respective features are:-

1.Ffmpeg

  • Capable of achieving the above goal and has extensive answers and explanations on sites like SO, however
  • Increases the APK size by 20-30mb (large library)
  • Runs the risk of not working properly on certain 64-bit devices

2.MediaRecorder

  • Reliable and supported by most devices
  • Will store files in .mp4 format (unless converted to h264)
  • Easier for playback (no decoding needed)
  • Adds the mp4 and 3gp headers
  • Increases latency according to this question

3.MediaCodec

  • Low level
  • Will require MediaCodec, MediaMuxer, and MediaExtractor
  • Output in h264 ( without using MediaMuxer for playback )
  • Good for video manipulations (though, not required in my use case)
  • Not supported by pre 4.3 (API 18) devices
  • More difficult to implement and code (my opinion - please correct me if I am wrong)
  • Unavailability of extensive information, tutorials, answers or samples (Bigflake.com being the only exception)

After spending days on this, I still can't figure out which approach suits my particular use case. Please elaborate on what I should do for my application. If there's a completely different approach, then I am open to that as well.

My biggest criteria are that the video encoding process be as efficient as possible and the video to be stored in the cloud should have the lowest possible space usage without compromising on the video quality.

Also, I'd be grateful if you could suggest the appropriate format for saving and distributing the video in Firebase Storage, and point me to tutorials or samples of your suggested approach.

Thank you in advance! And sorry for the long read.


Solution

  • Your overview on this topic is applicable to the point. I'll just add my 2 cents on this topic that you might have missed as addition:

    1.FFMpeg

    • +/-If you build your own SO then you can reduce the size down to about 2-3 MB depending on the use-case of course. Editing a 6000 lines buildscript takes time and effort though

    • ++Supports wide range of formats (almost everything)

    • ++Results are the same for every device

    • ++Any resolution supported

    • --High energy consumption due do SW-En-/Decoding, while also making it slow. There is a plugin to support lib-stagefright, but it doesn't work on many devices (as of May 2016)

    • --Licensing can be problematic depending on your location and use-case. I'm not a lawyer, but we had legal consulting on this topic and it's quite complex.

    2. MediaRecorder

    • ++Easiest to implement (simplified access to mediacodec/libstagefright) Raw data gets passed to the encoder directly so no messing around there

    • ++HW Accelerated on most devices. Makes it fast and energy saving.

    • ++Delay only applies to live streaming

    • --Dependent on implementation of HW-manufacturers

    • --Results may vary from device to device

    • ++No licensing problems

    3.MediaCodec

    • +/-Most of 2.MediaRecorder applies to this as well (apart from ease of use)

    • ++Most flexible access to HW-en-/decoding

    • --Hard to use for cases that were not thought of (e.g. mixing videos from different sources)

    • +/-Delay for streaming can be eliminated (is tricky though)

    • --HW-manufacturers sometimes don't implement things correctly (e.g the Samsung Galaxy S5 sometimes produces a SIG-SEV if live data from some DLSR is fed to the encoder. Works fine for a while, then all of a sudden it's SIG-SEV. This might be the dslr's fault, but the SIG-SEV is not avoidable and crashes the app, which in the end is the app developers fault ;) )

    • --If used without MediaMuxer you need either good understanding of media containers or rely on 3rd party libraries

    The list is obviously not complete and some points might not be correct. The last time I worked with video was almost half a year ago.

    As for your use-case I would recommend using MediaRecorder since it is the easiest to implement, supported on all devices, and offers a good deal of quality/size option. FFMpeg produces better results for the same storage size, but takes longer (extreme case, DSLR live footage was encoded 30 times faster), and is more energy consuming. As far as I understand your use-case, there is no need to fiddle around with MediaCodec since you want to encode and decode only.

    I suggest using VP8 or 9 since you wont run into licensing problems. Again I'm no lawyer but distributing H264 over your own server might make you a broadcasting station, so i was told.

    Hope this helps you in your decision making