先上代码
public class MainActivity extends AppCompatActivity implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
private MediaProjectionManager mediaProjectionManager;
private GLSurfaceView surfaceview;
private LinearLayout linearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout = ((LinearLayout) findViewById(R.id.linearlayout));
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
/**
* 初始化摄像头
*/
private void initCamera() {
surfaceview = new GLSurfaceView(this);
linearLayout.addView(surfaceview);
surfaceview.setEGLContextClientVersion(2);
surfaceview.setRenderer(this);
}
private MediaProjection mediaProjection;
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), 0);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
initCamera();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
setupGraphics();
setupVertexBuffer();
setupTexture();
//
}
private int width=1080;
private int height=1920;
private MediaPlayer mediaPlayer;
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
this.width = width;
this.height = height;
// if (mediaPlayer == null) {
// mediaPlayer = new MediaPlayer();
// mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// @Override
// public void onPrepared(MediaPlayer mp) {
// mp.start();
// }
// });
// Surface surface = new Surface(videoTexture);
// mediaPlayer.setSurface(surface);
// surface.release();
// try {
// mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath()+"/1.mp4");
// mediaPlayer.prepareAsync();
// } catch (IOException e) {
// e.printStackTrace();
// }
// } else {
// mediaPlayer.start();
// }
Surface surface = new Surface(videoTexture);
VirtualDisplay display = mediaProjection.createVirtualDisplay("aa", 1080, 1920, 32,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null);
}
private float[] videoTextureTransform = new float[16];
@Override
public void onDrawFrame(GL10 gl) {
synchronized (this) {
if (frameAvailable) {
videoTexture.updateTexImage();
videoTexture.getTransformMatrix(videoTextureTransform);
frameAvailable = false;
}
}
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textures[0]);
// Draw a rectangle and render the video frame as a texture on it.
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
// GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// GLES20.glViewport(0, 0, width, height);
this.drawTexture();
}
private int shaderProgram;
int textureParamHandle;
int textureCoordinateHandle;
int positionHandle;
int textureTranformHandle;
private static short drawOrder[] = {0, 1, 2, 0, 2, 3};
private FloatBuffer vertexBuffer;
private ShortBuffer drawListBuffer;
private static float squareSize = 0.5f;
private static float squareCoords[] = {
-squareSize, squareSize, // top left
-squareSize, -squareSize, // bottom left
squareSize, -squareSize, // bottom right
squareSize, squareSize}; // top right
private FloatBuffer textureBuffer;
private float textureCoords[] = {
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f};
private int[] textures = new int[1];
private SurfaceTexture videoTexture;
private void setupGraphics() {
final String vertexShader = RawResourceReader.readTextFileFromRawResource(this, R.raw.vetext_sharder);
final String fragmentShader = RawResourceReader.readTextFileFromRawResource(this, R.raw.fragment_sharder);
final int vertexShaderHandle = ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader);
final int fragmentShaderHandle = ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader);
shaderProgram = ShaderHelper.createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle,
new String[]{"texture", "vPosition", "vTexCoordinate", "textureTransform"});
GLES20.glUseProgram(shaderProgram);
textureParamHandle = GLES20.glGetUniformLocation(shaderProgram, "texture");
textureCoordinateHandle = GLES20.glGetAttribLocation(shaderProgram, "vTexCoordinate");
positionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
textureTranformHandle = GLES20.glGetUniformLocation(shaderProgram, "textureTransform");
}
private void setupVertexBuffer() {
// Draw list buffer
ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
// Initialize the texture holder
ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareCoords);
vertexBuffer.position(0);
}
private void setupTexture() {
ByteBuffer texturebb = ByteBuffer.allocateDirect(textureCoords.length * 4);
texturebb.order(ByteOrder.nativeOrder());
textureBuffer = texturebb.asFloatBuffer();
textureBuffer.put(textureCoords);
textureBuffer.position(0);
// Generate the actual texture
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glGenTextures(1, textures, 0);
// checkGlError("Texture generate");
GLES20.glBindTexture(GLES20.GL_TEXTURE_BINDING_2D, textures[0]);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
// checkGlError("Texture bind");
videoTexture = new SurfaceTexture(textures[0]);
videoTexture.setOnFrameAvailableListener(this);
}
private boolean frameAvailable = false;
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
synchronized (this) {
Log.e("---", "onFrameAvailable: ");
frameAvailable = true;
}
}
private void drawTexture() {
// Draw texture
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer);
GLES20.glEnableVertexAttribArray(textureCoordinateHandle);
GLES20.glVertexAttribPointer(textureCoordinateHandle, 4, GLES20.GL_FLOAT, false, 0, textureBuffer);
GLES20.glUniformMatrix4fv(textureTranformHandle, 1, false, videoTextureTransform, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
}
}
fragment_shader
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES texture;
varying vec2 v_TexCoordinate;
void main () {
vec4 color = texture2D(texture, v_TexCoordinate);
gl_FragColor = color;
}
vetext_shader
attribute vec4 vPosition;
attribute vec4 vTexCoordinate;
uniform mat4 textureTransform;
varying vec2 v_TexCoordinate;
void main () {
v_TexCoordinate = (textureTransform * vTexCoordinate).xy;
gl_Position = vPosition;
}