【问题标题】:Android 4K Video Record - Everything works fine but produced video file always 1080p?Android 4K 视频录制 - 一切正常,但生成的视频文件总是 1080p?
【发布时间】:2018-02-10 00:35:36
【问题描述】:

我正在开发一个使用 camera2 API 捕获 4K 视频的应用 - 不显示预览表面,也没有录制音频。

我使用的是运行 Android 7.0.0 的 LG G5。设备在查询时报告 camera2 API 的完整实现。原生相机应用程序以 4K 录制就好了。 mediarecorder 报告的分辨率证实了 4K 的可用性:

resolutions from log

我的初始化 MediaRecorder 的代码如下。我通过使用 setProfile 来执行此操作,因为我无法设置配置文件而不让程序抛出异常,因为我没有设置任何音频录制设置(因为我不想或不在乎录制音频):

        vidRecorder = new MediaRecorder();
        vidRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        vidRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        vidRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        vidRecorder.setVideoFrameRate(30);
        vidRecorder.setCaptureRate(30);

        vidRecorder.setVideoEncodingBitRate(35000000);
        vidRecorder.setVideoSize(3840, 2160);

        vidRecorder.setOutputFile(videoFilename);

        vidRecorder.prepare();

上面的日志中没有显示任何问题。输出格式和编码器与 VLC 报告的手机原生应用生成的 4K 视频文件相匹配。

除了生成的视频文件始终为 1920x1080p 之外,上述所有内容都运行良好!我不知道为什么会这样。提前感谢您的帮助。

【问题讨论】:

  • 附加信息:我尝试使用手动设置分辨率的配置文件进行录制:CamcorderProfile profile = CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH); profile.videoFrameWidth = 3840; profile.videoFrameHeight = 2160; profile.videoBitRate = (int)(profile.videoBitRate*2.8); vidRecorder.setProfile(profile); 上面的代码再次编译并运行没有错误,但视频文件仍然是 1080p。啊!
  • 信息:除了 3840x2160p 及以上(3264x2448 工作正常并生成匹配的 res 文件)之外,mediarecorder 输出列表中列出的所有分辨率似乎都有效。设置高于该分辨率的任何分辨率都会导致程序正常运行,但会生成 1080p 视频文件。多么令人沮丧。
  • whelp,据我所知,这不起作用的原因是制造商 (LG) 已将 4K 录制锁定到除本机应用程序之外的所有内容。我提到的所有其他表明可以录制 4K 的指标都没有实际意义——除非我使用本机应用程序,否则无论如何手机都不会录制 4K。太好了。

标签: android video capture android-camera2


【解决方案1】:

您必须启用 OpenGL ES 3.0 或更高版本。然后使用 GLES30 而不是 GLES20 或 GLES10 使用自定义类将 SurfaceView 覆盖为 GLSurfaceView 用于 Camera2 API 预览。

理想情况下,您会使用 GLES32,因为它支持 8K。

https://android.googlesource.com/platform/development/+/abededd/samples/browseable/Camera2Video/src/com.example.android.camera2video/Camera2VideoFragment.java

此 Camera2Video 示例使用 AutoFitTextureView:

https://github.com/googlearchive/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/AutoFitTextureView.java

你会想要使用 GLSurfaceView:

https://android.googlesource.com/platform/frameworks/base/+/master/opengl/java/android/opengl/GLSurfaceView.java

https://android.googlesource.com/platform/frameworks/base/+/master/graphics/java/android/graphics/SurfaceTexture.java

https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r2.1/core/java/android/view/Surface.java

这很乏味但并不困难。您只需将 GLES10 或 GLES20 替换为 GLES30 或理想情况下的 GLES32。

编辑:

我认为 Android 操作系统会自动使用最高 OpenGL ES 版本,这就是为什么 MediaPlayer 可以在 OpenGLES 3.0 上播放 4K 视频,但在 OpenGL ES 2.0 上显示黑色图像。

如果您的相机应用无法捕捉 4K,请尝试在 MediaPlayer 中播放 4K 视频,看看会发生什么:

Android: Play local video with mediaplayer

否则,您将不得不从 Camera2 API 中的 SurfaceTexture 中找到 updateTexImage() 的用法并使用 GLES30。 OpenGL ES 用在什么地方不是很清楚,但在 SurfaceTexture.java 中明确引用了它

Camera2 ImageCapture 似乎完全绕过了 Surface。虽然我可能弄错了。

关于 MediaPlayer 无法播放 4K 视频,LG G5 可能只支持 OpenGL ES 2.0。

4K 要求

  1. 设备必须支持 OpenGL ES 3.0 或更高版本
  2. Android 操作系统必须在 Surface、Surface Texture 上调用 OpenGL ES 3.0 或更高版本(尝试 API 31)
  3. Camera2 私有 API 必须调用 OpenGL ES 3.0 或更高版本(尝试 API 31)

编辑

这个答案谈到了使用 OpenGL 修改 SurfaceView。

Modifying camera output using SurfaceTexture and OpenGL

【讨论】:

    猜你喜欢
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 2018-10-19
    相关资源
    最近更新 更多