android 视频截屏代码,android视频截屏&手机录屏实现代码

本文介绍了android视频截屏&手机录屏实现代码,分享给大家,希望对大家有帮助

问题

在android中有时候我们需要对屏幕进行截屏操作,单一的截屏操作好解决可以通过activity的顶层view DecorView获取一个bitmap,得到就是当前activity上面的全部视图。

View view = activity.getWindow().getDecorView();

view.setDrawingCacheEnabled(true);

view.buildDrawingCache();

Bitmap bmp = view.getDrawingCache();

DisplayMetrics dm = new DisplayMetrics();

activity.getWindowManager().getDefaultDisplay().getMetrics(dm);

Bitmap ret = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);

view.destroyDrawingCache();

如果activity中包含一些视频播放器比如SurfaceView GLSurfaceView TextureView,在调用截屏代码会发现播放视频的部分是黑屏的,原因是这几种视频渲染的view通过以上代码拿到的是缓冲区不是真正的图像。

解决办法

android5.0以上系统提供了一个 MediaProjectionManager类来对手机进行录屏操作,也支持获取手机的Image图像的操作,知道了这些我们就可以通过提供的api来进行截屏操作了。

这里通过Service来操作截屏和录屏的api

1.绑定截屏的Service

Intent intent = new Intent(this, ScreenService.class);

bindService(intent, mServiceConnection, BIND_AUTO_CREATE);

public void onServiceConnected(ComponentName className, IBinder service) {

DisplayMetrics metrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(metrics);

ScreenService.RecordBinder binder = (ScreenService.RecordBinder) service;

recordService = binder.getRecordService();

recordService.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);

mButton.setEnabled(true);

mButton.setText(recordService.isRunning() ? "结束" : "开始");

}

2.请求权限 onActivityResult 方法中回调。

Intent captureIntent = projectionManager.createScreenCaptureIntent();

startActivityForResult(captureIntent, RECORD_REQUEST_CODE);

3c23088c70e48b9aeca613b2e8de0092.png

成功后

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {

//######## 截屏逻辑 ########

mediaProjection = projectionManager.getMediaProjection(resultCode, data);

recordService.setMediaProject(mediaProjection);

recordService.initImageReader();

}

}

3. 获取截屏

@Override

public void onClick(View view) {

//######## 截屏逻辑 ########

Bitmap bitmap = recordService.getBitmap();

mImageView.setImageBitmap(bitmap);

}

96875abac005c3fd715c4810a22d8127.png

录屏

录屏需要初始化一些录屏参数,输入麦克风类型视频类型,保存路径等

private void initRecorder() {

mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);

mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

mediaRecorder.setOutputFile(

getSavePath() + System.currentTimeMillis() + ".mp4");

mediaRecorder.setVideoSize(width, height);

mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);

mediaRecorder.setVideoFrameRate(30);

try {

mediaRecorder.prepare();

} catch (IOException e) {

e.printStackTrace();

}

}

开始录屏

mediaRecorder.start();

保存路径

99486a8cc915eca906f3bb3a754d470b.png

完整Service代码

public class ScreenService extends Service {

private MediaRecorder mediaRecorder;

private VirtualDisplay virtualDisplay;

private boolean running;

private int width = 720;

private int height = 1080;

private int dpi;

private ImageReader mImageReader;

private MediaProjection mediaProjection;

@Override

public IBinder onBind(Intent intent) {

return new RecordBinder();

}

@Override

public void onCreate() {

super.onCreate();

running = false;

mediaRecorder = new MediaRecorder();

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

return super.onStartCommand(intent, flags, startId);

}

@Override

public void onDestroy() {

super.onDestroy();

}

public void setMediaProject(MediaProjection project) {

mediaProjection = project;

}

public boolean isRunning() {

return running;

}

public void setConfig(int width, int height, int dpi) {

this.width = width;

this.height = height;

this.dpi = dpi;

}

/**

* 开始录屏

*

* @return true

*/

public boolean startRecord() {

if (mediaProjection == null || running) {

return false;

}

initRecorder();

createVirtualDisplay();

mediaRecorder.start();

running = true;

return true;

}

/**

* 结束录屏

*

* @return true

*/

public boolean stopRecord() {

if (!running) {

return false;

}

running = false;

mediaRecorder.stop();

mediaRecorder.reset();

virtualDisplay.release();

mediaProjection.stop();

return true;

}

public void setMediaProjection(MediaProjection mediaProjection) {

this.mediaProjection = mediaProjection;

}

/**

* 初始化ImageRead参数

*/

public void initImageReader() {

if (mImageReader == null) {

int maxImages = 2;

mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, maxImages);

createImageVirtualDisplay();

}

}

/**

* 创建一个录屏 Virtual

*/

private void createVirtualDisplay() {

virtualDisplay = mediaProjection

.createVirtualDisplay("mediaprojection", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder

.getSurface(), null, null);

}

/**

* 创建一个ImageReader Virtual

*/

private void createImageVirtualDisplay() {

virtualDisplay = mediaProjection

.createVirtualDisplay("mediaprojection", width, height, dpi,

DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader

.getSurface(), null, null);

}

/**

* 初始化保存屏幕录像的参数

*/

private void initRecorder() {

mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);

mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

mediaRecorder.setOutputFile(

getSavePath() + System.currentTimeMillis() + ".mp4");

mediaRecorder.setVideoSize(width, height);

mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);

mediaRecorder.setVideoFrameRate(30);

try {

mediaRecorder.prepare();

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 获取一个保存屏幕录像的路径

*

* @return path

*/

public String getSavePath() {

if (Environment.getExternalStorageState()

.equals(Environment.MEDIA_MOUNTED)) {

String rootDir = Environment.getExternalStorageDirectory()

.getAbsolutePath() + "/" +

"ScreenRecord" + "/";

File file = new File(rootDir);

if (!file.exists()) {

if (!file.mkdirs()) {

return null;

}

}

return rootDir;

} else {

return null;

}

}

/**

* 请求完权限后马上获取有可能为null,可以通过判断is null来重复获取。

*/

public Bitmap getBitmap() {

Bitmap bitmap = cutoutFrame();

if (bitmap == null) {

getBitmap();

}

return bitmap;

}

/**

* 通过底层来获取下一帧的图像

*

* @return bitmap

*/

public Bitmap cutoutFrame() {

Image image = mImageReader.acquireLatestImage();

if (image == null) {

return null;

}

int width = image.getWidth();

int height = image.getHeight();

final Image.Plane[] planes = image.getPlanes();

final ByteBuffer buffer = planes[0].getBuffer();

int pixelStride = planes[0].getPixelStride();

int rowStride = planes[0].getRowStride();

int rowPadding = rowStride - pixelStride * width;

Bitmap bitmap = Bitmap.createBitmap(width +

rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);

bitmap.copyPixelsFromBuffer(buffer);

return Bitmap.createBitmap(bitmap, 0, 0, width, height);

}

public class RecordBinder extends Binder {

public ScreenService getRecordService() {

return ScreenService.this;

}

}

demo下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值