android 5.0增加了MediaProjectionManager,通过它我们可以简单的完成录屏的需求。
本文会简单介绍MediaProjectionManager的使用流程,通过MediaCodec获取到的264数据
MediaProjectionManager的用法
1.获取MediaProjectionManager实例
通过调用getSystemService方法获取MediaProjectionManager的实例
/**
* 初始化MediaProjectionManager
* **/
private void InitMPManager(){
mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
}
2.创建屏幕捕捉的Intent
获取到MediaProjectionManager的实例后,通过createScreenCaptureIntent方法获取Intnent,通过startActivityForResult启动Intent
/**
* 开始截屏
* **/
private void StartScreenCapture(){
Intent captureIntent = mMediaProjectionManager.createScreenCaptureIntent();
startActivityForResult(captureIntent, REQUEST_CODE_A);
}
3.在onActivityResult中获取MediaProjection实例
通过startActivityForResult启动intent后,在onActivityResult的回掉中获取MediaProjection的实例,这时候要开始初始化MediaCodec了,通过MediaCodec可以拿到Surface对像,通过MediaProjection对象的createVirtualDisplay方法,拿到VirtureDisplay对象,拿这个对象的时候,需要把Surface对象传进去。
获取MediaProjection
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
try {
MediaProjection mediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);
}
catch (Exception e){
}
}
初始化MediaCodec,获取Surface对象
try{
MediaFormat format = MediaFormat.createVideoFormat(Constant.MIME_TYPE, Constant.VIDEO_WIDTH, Constant.VIDEO_HEIGHT);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_BIT_RATE, Constant.VIDEO_BITRATE);
format.setInteger(MediaFormat.KEY_FRAME_RATE, Constant.VIDEO_FRAMERATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, Constant.VIDEO_IFRAME_INTER);
mEncoder = MediaCodec.createEncoderByType(Constant.MIME_TYPE);
mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mSurface = mEncoder.createInputSurface();
mEncoder.start();
}catch (IOException e){
}
获取VirtureDisplay对象
mVirtualDisplay =mMediaProjection.createVirtualDisplay(TAG + "-display", Constant.VIDEO_WIDTH, Constant.VIDEO_HEIGHT, Constant.VIDEO_DPI, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,
mSurface, null, null);
4.通过MediaCodec获取h264数据
通过MediaCodec获取264的代码,可以参考我的这个项目:Github
或者参考我之前的博客内容:android编码h264(二):MediaCodec 硬编码 h264(硬编码)
MediaCodec.BufferInfo mBufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
while (outputBufferIndex >= 0){
ByteBuffer outputBuffer = mEncoder.getOutputBuffers()[outputBufferIndex];
byte[] outData = new byte[mBufferInfo.size];
outputBuffer.get(outData);
if(mBufferInfo.flags == 2){
configbyte = new byte[mBufferInfo.size];
configbyte = outData;
}else if(mBufferInfo.flags == 1){
byte[] keyframe = new byte[mBufferInfo.size + configbyte.length];
System.arraycopy(configbyte, 0, keyframe, 0, configbyte.length);
System.arraycopy(outData, 0, keyframe, configbyte.length, outData.length);
if(outputStream != null){
outputStream.write(keyframe, 0, keyframe.length);
}
}else{
if(outputStream != null){
outputStream.write(outData, 0, outData.length);
}
}
mEncoder.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
}
到此,就基本结束了,写这个是为了一个项目做基础准备的,这个项目要解决如下问题:
不知道大家有没有遇到过,app开发完成后要给领导或者客户演示,如果领导在还好,如果不在,那么就会通过本地录像的方式来演示,我像通过rtsp或者rtmp流媒体的方式,将屏幕内容来实时的演示,目前项目才开始,代码会慢慢提交的。
项目地址:GitHub
这篇博客的代码也在这个工程里
————————————————
版权声明:本文为CSDN博主「sszpf」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ss182172633/article/details/79480853