My goal is to have ExoPlayer display a color video as black and white.
According to this this Github issue I should be able to achieve this with Open GL:
ExoPlayer will render video to any Surface. You could use SurfaceTexture, at which point you'd have video rendered into an OpenGL ES texture. Once you have that you can do anything that OpenGL lets you do, including using a pixel shader to transform the video to black and white.
In an older, but related, discussion in the Android Developers Google group Romain Guy gives some details as to how this should be done:
- Create an OpenGL context
- Generate an OpenGL texture name
- Create a SurfaceTexture with the texture name
- Pass the SurfaceTexture to Camera
- Listen for updates On SurfaceTexture update, draw the texture with OpenGL using the shader you want
Simple :)
And by playing around with Google's Cardboard example project I have determined that a fragment shader like the following one should be about right:
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);
}
I am also managed to have ExoPlayer render into a TextureView
instead of the usual SurfaceView
:
mPlayer.sendMessage(
videoRenderer,
MediaCodecVideoTrackRenderer.MSG_SET_SURFACE,
new Surface(mVideoTextureView.getSurfaceTexture())
);
Now, how do I wire everything together?
Where can I "apply" the shader to the TextureView
? Is that even possible or should I use a GLSurfaceView
instead? What would I need to do in the Renderer
?