如何将片段着色器应用到GLSurfaceView/TextureView?

4

我的目标是让ExoPlayer将彩色视频显示为黑白。

根据这个Github问题,我应该能够通过Open GL实现这一点:

ExoPlayer将视频渲染到任何Surface上。您可以使用SurfaceTexture,此时您将视频渲染到OpenGL ES纹理中。一旦您拥有了它,您就可以做任何OpenGL允许您做的事情,包括使用像素着色器将视频转换为黑白。

Android开发者Google组的旧但相关的讨论中,Romain Guy提供了如何完成此操作的详细说明:

  • 创建一个OpenGL上下文
  • 生成一个OpenGL纹理名称
  • 使用纹理名称创建SurfaceTexture
  • 将SurfaceTexture传递给相机
  • 监听更新,在SurfaceTexture更新时使用所需的着色器用OpenGL绘制纹理

简单 :)

通过尝试Google的Cardboard示例项目,我确定以下片段着色器应该是正确的:
precision mediump float;
varying vec4 v_Color;

void main() {
    float grayscale = v_Color[0] * 0.3 + v_Color[1] * 0.59 + v_Color[2] * 0.11;
    gl_FragColor = vec4(grayscale, grayscale, grayscale, 0.1);
}

我还成功地让ExoPlayer渲染到一个TextureView而不是通常的SurfaceView:
mPlayer.sendMessage(
    videoRenderer,
    MediaCodecVideoTrackRenderer.MSG_SET_SURFACE,
    new Surface(mVideoTextureView.getSurfaceTexture())
);

现在,我该如何将所有东西连接起来呢? 我应该在哪里“应用”着色器到TextureView上?这是否可能,还是我应该使用GLSurfaceView?在Renderer中需要做什么?

1
你看过这个吗:https://github.com/google/ExoPlayer/issues/1220 以及其中的链接? - Morrison Chang
谢谢,链接的博客文章确实提供了一个可行的解决方案!非常感谢! - david.mihola
嘿,大卫,我也在尝试做同样的事情,但是过去两天我都被卡住了。我看了一下 VidEffect 的 VideoSurfaceView 代码,但当我集成 exoplayer 后,视频是黑色的,但是有音频。如果你还有可行的解决方案,如果你能分享一下,那将意义重大。 - Udit Mukherjee
1个回答

1
我之前曾将片段着色器应用于ExoPlayer播放的视频。最有效的方法似乎是将视频播放到GLSurfaceView上,因为它们对自定义渲染器有很好的支持。
一个将OpenGL着色器应用于GLSurfaceView的工作示例可以从这里获取。它甚至已经作为其特效库的一部分包含了灰度片段着色器。现有代码需要进行一些小的重构,因为它使用的是MediaPlayer而不是ExoPlayer

1
谢谢!我根据@Morrison Chang评论中提供的博客文章建立了我的解决方案-它使用了一个“TextureView”,并将“Surface”传递给ExoPlayer。但也许我仍然需要切换到“GLSurfaceView”,因为我还需要支持VisualOn,而该播放器仅接受“SurfaceView”(而不是直接的“Surface”)。 - david.mihola

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接