Android - 在 MediaRecorder、MediaCodec 和 Ffmpeg 之间进行选择

Posted

技术标签:

【中文标题】Android - 在 MediaRecorder、MediaCodec 和 Ffmpeg 之间进行选择【英文标题】:Android - Choosing between MediaRecorder, MediaCodec and Ffmpeg 【发布时间】:2017-08-01 22:03:56 【问题描述】:

我正在开发适用于 android 的视频录制和共享应用程序。该应用程序的规格如下:-

从应用内部录制 10 秒(最长)的视频(不使用设备的相机应用) 没有进一步编辑视频 将视频存储在 Firebase 云存储 (GCS) 存储桶中 其他用户下载和播放该视频

从研究中,我在 SO 和其他资源上做了这个,我发现了以下内容(如果我错了,请纠正我):-

这三个选项及其各自的特点是:-

1.Ffmpeg

能够实现上述目标,并且在 SO 等网站上有广泛的答案和解释,但是 将 APK 大小增加 20-30mb(大型库) 存在无法在某些 64 位设备上正常工作的风险

2.媒体记录器

可靠并受到大多数设备的支持 将以 .mp4 格式存储文件(除非转换为 h264) 播放更轻松(无需解码) 添加 mp4 和 3gp 标头 根据this question增加延迟

3.媒体编解码器

低级 将需要 MediaCodec、MediaMuxer 和 MediaExtractor h264 输出(不使用 MediaMuxer 进行播放) 适用于视频操作(但在我的用例中不是必需的) 4.3 (API 18) 之前的设备不支持 更难实现和编码(我的意见 - 如果我错了,请纠正我) 无法获得大量信息、教程、答案或示例(Bigflake.com 是唯一的例外)

在这方面花了几天时间后,我仍然无法确定哪种方法适合我的特定用例。请详细说明我应该为我的申请做些什么。如果有完全不同的方法,那么我也对此持开放态度。

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

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

提前感谢您!很抱歉读了这么久。

【问题讨论】:

使用像 mobile-ffmpeg 这样的预构建 ffmpeg 解决方案可以显着减少第一个替代方案的麻烦。将添加到您的 APK 的最小大小约为 7MByte。 【参考方案1】:

您对此主题的概述适用于这一点。 我将在这个主题上加上你可能错过的 2 美分:

1.FFMpeg

+/-如果您构建自己的 SO,那么您当然可以根据用例将大小减小到大约 2-3 MB。编辑一个 6000 行的构建脚本需要时间和精力

++支持多种格式(几乎所有格式)

++每个设备的结果都相同

++支持任何分辨率

-- 执行 SW-En-/Decoding 会导致高能耗,同时也会使其变慢。有一个支持 lib-stagefright 的插件,但它不适用于许多设备(截至 2016 年 5 月)

--根据您的位置和用例,许可可能会出现问题。我不是律师,但我们就这个话题进行过法律咨询,而且非常复杂。

2。媒体记录器

++最容易实现(简化对 mediacodec/libstagefright 的访问)原始数据直接传递给编码器,因此不会乱七八糟

++HW 在大多数设备上加速。使其快速且节能。

++Delay 仅适用于直播

--取决于硬件制造商的实施

--结果可能因设备而异

++没有许可问题

3.MediaCodec

+/-Most of 2.MediaRecorder 也适用于此(除了易用性之外)

++最灵活的HW-en-/解码访问

--难以用于未曾想到的情况(例如混合来自不同来源的视频)

可以消除流式传输的+/-延迟(虽然很棘手)

--硬件制造商有时无法正确实现(例如,如果将来自某些 DLSR 的实时数据馈送到编码器,三星 Galaxy S5 有时会产生 SIG-SEV。工作正常一段时间,然后一切正常突然是 SIG-SEV。这可能是 dslr 的错,但是 SIG-SEV 是无法避免的,并且导致应用程序崩溃,这最终是应用程序开发人员的错;))

--如果在没有 MediaMuxer 的情况下使用,您需要对媒体容器有很好的理解或依赖 3rd 方库

列表显然不完整,有些点可能不正确。我上一次与视频合作大约是半年前。

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

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

希望这对您的决策有所帮助

【讨论】:

这个答案非常有帮助,真的帮助我解决了问题。谢谢! FFmpeg 很慢,但似乎最近它得到了 MediaCodec 支持,MediaRecorder 只适用于清晰的视频,通常人们不会问在 Android 上使用什么来录制视频,直到他们想要处理帧在录制之前,实际上可以使用 MediaRecorder,但它的 bug 很少工作:***.com/questions/51332386/… 所以 MediaRecorder 仅适用于没有处理帧的清晰视频 在某些设备上 MediaRecorder 存在问题(不会录制视频..),带有 Camera2 API 和 Surface 视频源:github.com/googlesamples/android-Camera2Video/issues/86

以上是关于Android - 在 MediaRecorder、MediaCodec 和 Ffmpeg 之间进行选择的主要内容,如果未能解决你的问题,请参考以下文章

android MediaRecorder录制音频

使用MediaRecorder录制音频

Android MediaRecorder解析

在 Android 中使用 AudioRecorder/MediaRecorder 录制 FLAC 音频

Android 10 源码MediaRecorder 录像流程:MediaRecorder 配置

Android App调用MediaRecorder实现录音功能的实例