2017-09-05 119 views
6

假设我们在Android上Surface能显示视频(例如H264)用的MediaPlayer:视频在机器人:改变视觉特性(例如饱和度,亮度)

1)是否有可能改变显示饱和,对比&显示在平面视频上的亮度?实时?例如。图像可以使用setColorFilter有什么类似的Android来处理视频帧?

替代问题(如果没有1太难了。):

2)如果我们想导出此视频与例如饱和度增加,我们应该使用编解码器,例如MediaCodec。我们应该在编解码器/保存操作之前使用哪些技术(方法,类,库等)来应用饱和度更改?

+0

你想,可以操纵用于显示视频现成的库(如下面的答案),或者你有其他要求不允许呢?答案中的链接项目演示了如何使用具有'MediaPlayer'的'GLSurfaceView'并应用OpenGL着色器在显示器上执行过滤。如果您不需要导出已过滤的视频,那绝对是一种合理的方法。你的'Surface'现在从哪里来? – Dave

+0

嗨@Dave,我目前正在研究如何调整显示的视频(通常在表面上),还导出调整后的视频。所以我没有具体的“表面” - 这就是我正在寻找:) – Diolor

回答

2

仅供显示,一种简单的方法是使用GLSurfaceViewSurfaceTexture来渲染视频帧,以及MediaPlayer。 Prokash的答案链接到一个开放源代码库,显示如何实现这一点。如果你一起搜索这些术语,还有其他许多例子。采取这种路线,您可以将视频帧绘制为OpenGL纹理,并创建OpenGL着色器来操纵纹理的渲染方式。 (如果这足以满足您的要求,我会建议询问Prokash并接受他的回答。)

同样,您可以使用OpenGL工具MediaCodecMediaExtractor来解码视频帧。 MediaCodec将被配置为输出到SurfaceTexture,所以您不需要做更多的工作,只需编写一些样板文件即可获得输出缓冲区。过滤过程将与MediaPlayer相同。有许多使用MediaCodec作为可用解码器的例子。 herehere。将这些示例中使用的TextureViewSurfaceView替换为Prokash示例的GLSurfaceView应该相当直接。

此方法的优点是您可以访问媒体文件中的所有单独轨道。因此,您应该可以使用OpenGL过滤视频轨道并直接复制其他轨道以导出。您可以在编码模式下使用MediaCodec,使用GLSurfaceViewSurface作为输入,使用MediaMuxer将其全部重新组合。你可以在BigFlake看到几个相关的例子。

您可以使用不带SurfaceMediaCodec直接访问解码的字节数据并以此方式操作。 This example说明了这种方法。您可以操作这些数据并将其发送到编码器进行导出或按您认为合适的方式进行渲染。处理原始字节数据有一些额外的复杂性。请注意,我喜欢这个例子,因为它说明了分别处理音频和视频轨道。

您也可以使用FFMpeg,无论是本地代码还是通过其中一个Java包装。此选项更适合导出而不是立即播放。对于某些试图使FFMpeg可用于Java的库,请参见herehere。它们基本上是命令行界面的包装。您需要做一些额外的工作才能通过FFMpeg管理播放,但这绝对是可行的。

如果您有任何疑问,请随时询问,并且我会尝试阐述对您的用例最有意义的任何选项。

+0

嗨戴夫,你肯定值得赏赐,因为它非常分析。创建可视过滤器并导出它们的最均衡的解决方案看起来像使用'MediaCodec'手动工作。当然,我正在寻找是否可以使用FFMpeg(它看起来很棒),并带有一些“预览”的可能性。谢谢! – Diolor

1

如果您使用的是支持视频滤镜玩家,那么你可以做到这一点。

这样的球员的实施例是VLC,其围绕FFMPEG [1]建造。

VLC很容易编译为Android。然后,你需要的是libvlc(aar文件),你可以构建自己的应用程序。请参阅编译指令here

您还需要write your own module。只需复制一个现有的并修改它。不用说,VLC提供强大的转码和流媒体功能。

至于强大的VLC Android版,它有一个巨大的缺点 - 视频滤波器不能与硬件解码工作(仅限Android)。这意味着整个视频处理都在CPU上。


您的其他选项是在GLSurfaceView和TextureView等表面上使用GLSL/OpenGL。这保证了GPU的能力。

相关问题