【问题标题】:How to encode camera frames into mp4 on android如何在android上将相机帧编码为mp4
【发布时间】:2025-12-16 20:05:02
【问题描述】:

我从 640x480(对我来说足够)的 android 相机中获取相机预览帧,并对它们进行一些修改。但现在我需要将它们编码为新的MP4 文件(带音频)。

这怎么可能?我不能使用ffmpeg,因为它的许可证不太好,但我发现Stagefright 框架应该可以做到这一点。但是我没有找到任何官方文档或教程来做我需要做的事情。

请问有没有办法用这个框架做到这一点?我不需要代码,我会很高兴为我指出正确的方向。

【问题讨论】:

    标签: android camera capture frames stagefright


    【解决方案1】:

    有一种场景可以实现所描述的用例。考虑将Camera 输出馈送到OpenGL 库的场景,其中一些效果应用于需要记录的预览帧。

    在这种情况下,您可以将传统的MediaRecorderGrallocSource 一起使用,而不是CameraSource。设置如下所示:

    MediaRecorder 设置为GrallocSource。用于记录的输入表面由实现SurfaceTextureClientCamera + OpenGL 组合操作提供。在SurfaceMediaSource_test modules 中可以找到一个很好的例子。

    【讨论】:

    • 实际上,我不知道你在说什么 :D 但是会做更多的研究。听起来很有趣,谢谢。
    【解决方案2】:
    如果您必须支持 API 9 及更高版本,

    stagefright 非常好。但正如你所见,这个框架不是官方的。您可以使用platform/frameworks/av 中的示例代码,风险自负。

    google 源包括 CameraSource,它直接将相机帧提供给编码器。虽然这种方法可能更有效(像素根本不会复制到用户空间),但它不允许操作。可以修改 C++ 源代码,但我强烈建议使用 Java 访问 Camera,并通过 JNI 将 preview frames 传递给 stagefrght (OpenMAX) 编码器。在某些设备上,这可能会迫使您使用软件编码器。您必须将视频帧转换为编码器的 YUV 平面格式。请参阅 libyuv 了解优化的转换器。

    如果您可以限制对 API 16 及更高版本的支持,则使用官方 Java MediaCdec API 会更安全。

    【讨论】:

    • 不幸的是,我不能限制为 api 16 它的市场份额太低:/ 但感谢您提供示例代码,希望我能在那里找到一些东西
    • 好吧,我刚刚研究了几个小时的怯场,现在我很迷茫。我的目标是在 API 14+ 设备上录制 480x480 视频。但我完全不知道该怎么做。我认为可以覆盖 MediaRecorder 的 CameraSource 以提供我想要的流,或者剪辑它或其他任何东西。我看过 JNI,我知道如何在应用程序中使用我的自定义本机代码,但我完全不知道如何通过 JNI 录制视频。还有什么要记录的...你能帮忙吗?谢谢
    • 我可能已经找到了解决方案。我只需要在android的本机源代码中找到编码方法,然后让我的jni调用它并传递相机帧。没关系?
    • 请注意,stagefright (OpenMAX) 视频编码器具有硬件加速模式,可以直接访问相机缓冲区。这对您不利,因为您要修改(剪辑)源。在某些设备上,这可能会迫使您使用软件编码器。见update
    • 我打算这样做:我从相机中捕捉到 onPreviewFrame,所以我得到了 byte[] 帧数组。然后我将该字节数组传递给我的 cpp 类,该类将管理将其编码为 mp4 文件(几乎)与androidxref.com/4.2.2_r1/xref/frameworks/av/cmds/stagefright/… 相同的方式。这样我是否会使用 hw 进行编码?