Android:编码的相机预览帧总是横向的。如何旋转?

Posted

技术标签:

【中文标题】Android:编码的相机预览帧总是横向的。如何旋转?【英文标题】:Android: Encoded Camera Preview Frames always in landscape. How to rotate? 【发布时间】:2016-05-05 05:39:58 【问题描述】:

目标:无论设备的方向如何,都以正确的方向将 android 相机流式传输到 Wowza 服务器(即视频始终正面朝上)

我已经查看了此处有关相机方向的所有问题,到目前为止,它们似乎都只是更改呈现到屏幕上的预览或在 MP4 文件中设置一个标志(不适合我的用例:流式传输)。

我正在将相机帧流式传输到 Wowza 服务器,而在 Wowza 服务器上接收到的视频始终是横向的。如果手机始终保持相同的方向,这很好,但我不能保证我的用户会这样做。根据我收集到的信息,当您直接从相机中抓取帧并将它们提供给编码器时,您将获得设备相机的自然方向(在我的情况下可能是横向安装的),这完全不受预览的影响.这是有问题的,因为如果设备在流期间旋转,图像也会随之旋转。

我尝试使用 openGL 矩阵在自定义 GLSurfaceView.Renderer 中转换预览,它所做的只是转换屏幕上的视图,而不是发送到编码器的帧。

我已阅读 Grafika 的示例,但不确定在将帧输入编码器之前我需要旋转帧的哪个位置。我使用 SurfaceTexture 作为相机预览,然后渲染到 GLSurfaceView(并使用我自己的自定义 GLSurfaceView.Renderer)。

如何将帧旋转到编码器?

理想情况下,我会在 openGL 中执行此操作。我曾考虑在填充 mediacodec.dequeueInputBuffer 缓冲区之前旋转帧,但这将使用 CPU 完成,并且由于实时应用程序,我很谨慎。也许我忽略了一些关于预览的东西。我已经看到其他广播应用程序会在设备旋转时拆除 UI 上的 Preview 层并重新构建它。

参考资料:

https://github.com/Kickflip/kickflip-android-sdk/

https://github.com/google/grafika

【问题讨论】:

【参考方案1】:

Grafika 中的相机活动每帧渲染两次:一次用于显示,一次用于编码。您想做同样的事情,但需要进行轮换(并对 MediaCodec / MediaRecorder 配置进行适当调整,即 720x1280 与 1280x720)。

例如,考虑drawFrame() method in ContinuousCapture。它选择 SurfaceView 的 EGLSurface,进行绘制,然后切换到视频编码器的 EGLSurface 并调用相同的绘制方法。它甚至会调用drawExtra(),只是为了表明它可以。

在这两种情况下,您只是将 GLES 渲染到 EGLSurface 上,而 EGLSurface 从底层 Surface 获取其尺寸,该 Surface 来自 SurfaceView 或 MediaCodec。如果您修改FullFrameRect#drawFrame() 以采用矩阵参数,并传入一个旋转矩阵来代替它当前使用的单位矩阵,您应该会得到您想要的结果。

【讨论】:

非常感谢您这么快的回复!我的表面来自 MediaCodec (mediaCodec createInputSurface()),所以如果在编码器运行时方向发生变化,你说我将不得不停止它,并用适当的尺寸重新配置它,并传入一个旋转矩阵 ( Matrix.rotateM())?我还必须再次调用 createInputSurface,对吗?我的openGL经验为零,但我想我可以弄清楚。我将首先在 ContinuousCapture 和 FullFrameRect 中尝试您建议的更改,如果我有任何问题,请告诉您。 中流分辨率更改是可能的,但我没有使用它们(参见例如***.com/questions/31321685)。停止和重新启动 MediaCodec 将起作用。另一种方法是在旋转后对视频进行信箱或邮筒,但这看起来不太好。 “来自相机的纹理”活动缩放和旋转相机馈送;实现细节见Sprite2d#recomputeMatrix()

以上是关于Android:编码的相机预览帧总是横向的。如何旋转?的主要内容,如果未能解决你的问题,请参考以下文章

Android - 相机预览是横向的

Android - 相机预览是横向的

如何在一帧后面显示预览相机并拍照包括帧

Android 相机预览帧时间戳

即使我将应用程序清单设置为纵向,为啥我的 Android 相机预览仍显示横向?

如何在视频中保存相机预览帧?