Android 中的视频:更改视觉属性(例如饱和度、亮度)
Video in Android : change visual properties (e.g. saturation, brightness)
假设我们在 Android 中有一个 Surface
使用 MediaPlayer 显示视频(例如 h264):
1) surface视频显示的饱和度、对比度和亮度是否可以改变?实时?例如。图像可以使用setColorFilter
Android 中是否有类似的东西来处理视频帧?
备选题(如果第1题太难):
2) 如果我们想导出此视频,例如增加饱和度,我们应该使用编解码器,例如MediaCodec
。我们应该在 codec/save 操作之前使用什么技术(方法、class、库等...)来应用饱和度变化?
仅用于显示,一种简单的方法是使用 GLSurfaceView
, a SurfaceTexture
to render the video frames, and a MediaPlayer
。 Prokash 的答案链接到一个开源库,该库展示了如何实现这一点。如果您一起搜索这些术语,还有许多其他示例。采用这种方法,您将视频帧绘制到 OpenGL 纹理并创建 OpenGL 着色器来操纵纹理的渲染方式。 (我建议向 Prokash 询问更多详细信息,如果这足以满足您的要求,请接受他的回答。)
同样,您可以将 OpenGL 工具与 MediaCodec
and MediaExtractor
to decode video frames. The MediaCodec
would be configured to output to a SurfaceTexture
, so you would not need to do much more than code some boilerplate to get the output buffers rendered. The filtering process would be the same as with a MediaPlayer
. There are a number of examples using MediaCodec
as a decoder available, e.g. here and here 结合使用。将这些示例中使用的 TextureView
或 SurfaceView
替换为 Prokash 示例中的 GLSurfaceView
应该相当简单。
这种方法的优点是您可以访问媒体文件中的所有单独轨道。因此,您应该能够使用 OpenGL 过滤视频轨道并直接复制其他轨道以进行导出。您将在编码模式下使用 MediaCodec
,将 GLSurfaceView
中的 Surface
作为输入,并使用 MediaMuxer
to put it all back together. You can see several relevant examples at BigFlake.
您可以使用不带 Surface
的 MediaCodec
来直接访问解码的字节数据并以这种方式对其进行操作。 This example 说明了这种方法。您可以操作数据并将其发送到编码器以进行导出或按您认为合适的方式进行渲染。处理原始字节数据有一些额外的复杂性。请注意,我喜欢这个示例,因为它说明了分别处理音频和视频轨道。
您还可以将 FFMpeg, either in native code or via one of the Java wrappers out there. This option is more geared towards export than immediate playback. See here or here 用于某些试图使 FFMpeg 可用于 Java 的库。它们基本上是命令行界面的包装器。您需要做一些额外的工作才能通过 FFMpeg 管理播放,但这绝对可行。
如果您有任何疑问,请随时提问,我将尝试阐述对您的用例最有意义的任何选项。
如果您使用的是支持视频滤镜的播放器,那么您可以这样做。
这种玩家的例子是 VLC, which is built around FFMPEG [1]。
VLC 很容易为 Android 编译。然后您只需要 libvlc(aar 文件),您就可以构建自己的应用程序。请参阅编译说明 here.
您还需要write your own module。只需复制一个现有的并修改它。不用说,VLC 提供了强大的转码和流媒体功能。
作为 Android 的强大 VLC,它有一个巨大的缺点 - 视频过滤器不能与硬件解码一起使用(仅 Android)。这意味着整个视频处理都在 CPU.
您的其他选择是在 GLSurfaceView 和 TextureView 等表面上使用 GLSL/OpenGL。这保证了 GPU 的能力。
假设我们在 Android 中有一个 Surface
使用 MediaPlayer 显示视频(例如 h264):
1) surface视频显示的饱和度、对比度和亮度是否可以改变?实时?例如。图像可以使用setColorFilter
Android 中是否有类似的东西来处理视频帧?
备选题(如果第1题太难):
2) 如果我们想导出此视频,例如增加饱和度,我们应该使用编解码器,例如MediaCodec
。我们应该在 codec/save 操作之前使用什么技术(方法、class、库等...)来应用饱和度变化?
仅用于显示,一种简单的方法是使用 GLSurfaceView
, a SurfaceTexture
to render the video frames, and a MediaPlayer
。 Prokash 的答案链接到一个开源库,该库展示了如何实现这一点。如果您一起搜索这些术语,还有许多其他示例。采用这种方法,您将视频帧绘制到 OpenGL 纹理并创建 OpenGL 着色器来操纵纹理的渲染方式。 (我建议向 Prokash 询问更多详细信息,如果这足以满足您的要求,请接受他的回答。)
同样,您可以将 OpenGL 工具与 MediaCodec
and MediaExtractor
to decode video frames. The MediaCodec
would be configured to output to a SurfaceTexture
, so you would not need to do much more than code some boilerplate to get the output buffers rendered. The filtering process would be the same as with a MediaPlayer
. There are a number of examples using MediaCodec
as a decoder available, e.g. here and here 结合使用。将这些示例中使用的 TextureView
或 SurfaceView
替换为 Prokash 示例中的 GLSurfaceView
应该相当简单。
这种方法的优点是您可以访问媒体文件中的所有单独轨道。因此,您应该能够使用 OpenGL 过滤视频轨道并直接复制其他轨道以进行导出。您将在编码模式下使用 MediaCodec
,将 GLSurfaceView
中的 Surface
作为输入,并使用 MediaMuxer
to put it all back together. You can see several relevant examples at BigFlake.
您可以使用不带 Surface
的 MediaCodec
来直接访问解码的字节数据并以这种方式对其进行操作。 This example 说明了这种方法。您可以操作数据并将其发送到编码器以进行导出或按您认为合适的方式进行渲染。处理原始字节数据有一些额外的复杂性。请注意,我喜欢这个示例,因为它说明了分别处理音频和视频轨道。
您还可以将 FFMpeg, either in native code or via one of the Java wrappers out there. This option is more geared towards export than immediate playback. See here or here 用于某些试图使 FFMpeg 可用于 Java 的库。它们基本上是命令行界面的包装器。您需要做一些额外的工作才能通过 FFMpeg 管理播放,但这绝对可行。
如果您有任何疑问,请随时提问,我将尝试阐述对您的用例最有意义的任何选项。
如果您使用的是支持视频滤镜的播放器,那么您可以这样做。
这种玩家的例子是 VLC, which is built around FFMPEG [1]。
VLC 很容易为 Android 编译。然后您只需要 libvlc(aar 文件),您就可以构建自己的应用程序。请参阅编译说明 here.
您还需要write your own module。只需复制一个现有的并修改它。不用说,VLC 提供了强大的转码和流媒体功能。
作为 Android 的强大 VLC,它有一个巨大的缺点 - 视频过滤器不能与硬件解码一起使用(仅 Android)。这意味着整个视频处理都在 CPU.
您的其他选择是在 GLSurfaceView 和 TextureView 等表面上使用 GLSL/OpenGL。这保证了 GPU 的能力。