Android - 在MediaRecorder、MediaCodec和Ffmpeg之间如何选择?

22

我正在开发一款Android视频录制和分享应用程序。该应用程序的规格如下:

  • 在应用程序内录制最长10秒的视频(不使用设备的相机应用程序)
  • 视频不需要进一步编辑
  • 将视频存储在Firebase Cloud Storage (GCS) bucket中
  • 其他用户可以下载和播放视频

从我在 Stack Overflow 和其他来源所做的研究中,我发现了以下内容(如果我错了,请纠正我):

三种选项及其特点如下:

1. Ffmpeg

  • 能够达到上述目标,并且在类似于 Stack Overflow 的网站上有广泛的答案和解释,但
  • 会增加APK大小20-30MB(庞大的库)
  • 存在在某些64位设备上无法正常工作的风险

2. MediaRecorder

  • 可靠,受大多数设备支持
  • 将文件存储为.mp4格式(除非转换为h264)
  • 更容易进行回放(不需要解码)
  • 添加mp4和3gp头文件
  • 根据此问题增加延迟

3. MediaCodec

  • 低级别
  • 需要使用MediaCodec、MediaMuxer和MediaExtractor
  • 输出为h264格式(无需使用MediaMuxer进行回放)
  • 适用于视频操作(虽然在我的用例中不需要)
  • 不支持4.3以下(API 18)的设备
  • 更难实现和编码(我个人观点-如果我错了,请纠正我)
  • 缺乏广泛的信息、教程、答案或样本(Bigflake.com是唯一的例外)

我已经花了几天时间,但我仍然无法确定哪种方法适合我的特定用例。请详细说明我应该为我的应用程序做些什么。如果有完全不同的方法,我也愿意尝试。

我的最大标准是视频编码过程尽可能高效,并且存储在云中的视频在不影响视频质量的情况下占用空间最小。

此外,如果您可以建议在Firebase Storage中保存和分发视频的适当格式,并指向建议方法的教程或示例,我将不胜感激。

非常感谢!对于长篇阅读,很抱歉。


1
使用预构建的ffmpeg解决方案,如mobile-ffmpeg,可以显著减少第一种替代方案的麻烦。将添加到您的APK中的最小大小约为7MByte。 - Alex Cohn
1个回答

25

你对这个话题的概述很到位。我只是想补充一下你可能忽略的两点:

1. FFMpeg

  • +/-如果你自己构建SO,可以将大小缩小到约2-3 MB,当然这取决于使用情况。不过编辑6000行的构建脚本需要时间和精力。

  • ++支持广泛的格式(几乎所有格式)

  • ++结果对每个设备都是相同的

  • ++支持任何分辨率

  • --由于软件编解码而能量消耗高,同时也使其变慢。有一个插件支持lib-stagefright,但它不能在许多设备上使用(截至2016年5月)

  • --根据您所在地区和使用情况,许可证可能会有问题。我不是律师,但我们就此进行了法律咨询,这很复杂。

2.MediaRecorder

  • ++最容易实现(简化对mediacodec/libstagefright的访问),原始数据直接传递给编码器,因此没有烦恼

  • ++在大多数设备上进行硬件加速。使其快速且节省能源。

  • ++仅适用于实时流的延迟

  • --取决于硬件制造商的实现

  • --结果可能因设备而异

  • ++没有许可证问题

3.MediaCodec

  • +/-大部分与2.MediaRecorder相同(除了易用性)

  • ++对HW编解码具有最灵活的访问权

  • --难以处理未考虑到的情况(例如混合来自不同来源的视频)

  • 流媒体的+/-延迟可以被消除(但有技巧)

  • --硬件制造商有时不正确地实现某些功能(例如三星Galaxy S5有时会在将某些DSLR的实时数据馈送到编码器时产生SIG-SEV。一开始很好用,但突然间就是SIG-SEV了。这可能是相机的问题,但SIG-SEV无法避免并会导致应用程序崩溃,最终责任在应用程序开发人员身上;))

  • --如果没有使用MediaMuxer,你需要对媒体容器有良好的理解或依赖于第三方库

  • 这个列表显然不完整,有些点可能不正确。我上次处理视频是半年之前。

    至于您的用例,我建议使用MediaRecorder,因为它最容易实现,在所有设备上都受支持,并提供了良好的质量/大小选项。FFMpeg在相同的存储大小下产生更好的结果,但需要更长时间(极端情况下,DSLR实时镜头编码速度快了30倍),并且更耗能。 就我所理解的您的用例而言,您没有必要与MediaCodec打交道,因为您只想进行编码和解码。

    我建议使用VP8或9,因为您不会遇到许可问题。再次声明,我不是律师,但据说在自己的服务器上分发H264可能会使您成为广播电台。

    希望这些能帮助你做出决策


    1
    这个答案非常有帮助,真的帮我搞清楚了很多事情。谢谢! - masterwok
    1
    FFmpeg非常慢,但最近似乎已经支持MediaCodec。MediaRecorder仅适用于清晰的视频,通常人们在Android上进行视频录制时不会询问要使用什么,直到他们想在录制之前处理帧,这实际上是可能的,但它很容易出现错误,很少能正常工作:https://dev59.com/v1UK5IYBdhLWcg3wwSLg,因此MediaRecorder仅适用于没有处理帧的清晰视频。 - user924
    3
    在某些设备上,使用Camera2 API和Surface Video Source时,MediaRecorder存在缺陷(无法录制视频..):https://github.com/googlesamples/android-Camera2Video/issues/86 - user924

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接