您好,登錄后才能下訂單哦!
這篇文章主要介紹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);
成功后
@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); }
錄屏
錄屏需要初始化一些錄屏參數,輸入麥克風類型視頻類型,保存路徑等
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();
保存路徑
完整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; } }
以上是“android如何實現視頻截屏&手機錄屏”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。