欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

android視頻截屏&手機(jī)錄屏實(shí)現(xiàn)代碼

 更新時(shí)間:2017年07月27日 09:50:19   作者:金威JW  
本篇文章主要介紹了android視頻截屏&手機(jī)錄屏實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。

本文介紹了android視頻截屏&手機(jī)錄屏實(shí)現(xiàn)代碼,分享給大家,希望對大家有幫助

問題

在android中有時(shí)候我們需要對屏幕進(jìn)行截屏操作,單一的截屏操作好解決可以通過activity的頂層view DecorView獲取一個(gè)bitmap,得到就是當(dāng)前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,在調(diào)用截屏代碼會(huì)發(fā)現(xiàn)播放視頻的部分是黑屏的,原因是這幾種視頻渲染的view通過以上代碼拿到的是緩沖區(qū)不是真正的圖像。

解決辦法

android5.0以上系統(tǒng)提供了一個(gè) MediaProjectionManager類來對手機(jī)進(jìn)行錄屏操作,也支持獲取手機(jī)的Image圖像的操作,知道了這些我們就可以通過提供的api來進(jìn)行截屏操作了。

這里通過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() ? "結(jié)束" : "開始");
 }

2.請求權(quán)限 onActivityResult 方法中回調(diào)。

 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);
 }

錄屏

錄屏需要初始化一些錄屏參數(shù),輸入麥克風(fēng)類型視頻類型,保存路徑等

 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;
 }


 /**
 * 結(jié)束錄屏
 *
 * @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參數(shù)
 */
 public void initImageReader() {
   if (mImageReader == null) {
     int maxImages = 2;
     mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, maxImages);
     createImageVirtualDisplay();
   }
 }


 /**
 * 創(chuàng)建一個(gè)錄屏 Virtual
 */

 private void createVirtualDisplay() {
   virtualDisplay = mediaProjection
       .createVirtualDisplay("mediaprojection", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder
           .getSurface(), null, null);
 }


 /**
 * 創(chuàng)建一個(gè)ImageReader Virtual
 */
 private void createImageVirtualDisplay() {
   virtualDisplay = mediaProjection
       .createVirtualDisplay("mediaprojection", width, height, dpi,
           DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader
           .getSurface(), null, null);
 }


 /**
 * 初始化保存屏幕錄像的參數(shù)
 */
 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();
   }
 }


 /**
 * 獲取一個(gè)保存屏幕錄像的路徑
 *
 * @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;
   }
 }


 /**
 * 請求完權(quán)限后馬上獲取有可能為null,可以通過判斷is null來重復(fù)獲取。
 */
 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下載

github

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android Studio使用小技巧:布局預(yù)覽時(shí)填充數(shù)據(jù)

    Android Studio使用小技巧:布局預(yù)覽時(shí)填充數(shù)據(jù)

    這篇文章主要介紹了Android Studio使用小技巧:布局預(yù)覽時(shí)填充數(shù)據(jù),本文給出了代碼操作實(shí)例和效果圖例,需要的朋友可以參考下
    2015-05-05
  • Android中獲取狀態(tài)欄高度的兩種方法分享

    Android中獲取狀態(tài)欄高度的兩種方法分享

    在android應(yīng)用中,有時(shí)需要計(jì)算個(gè)View的位置,導(dǎo)致需要計(jì)算狀態(tài)欄高度。為以后方便,在此做個(gè)簡單記錄。下面這篇文章主要介紹了Android中獲取狀態(tài)欄高度的兩種方法,兩種方法分別給出了示例代碼,有需要的朋友可以參考借鑒。
    2017-02-02
  • 詳解Flutter WebView與JS互相調(diào)用簡易指南

    詳解Flutter WebView與JS互相調(diào)用簡易指南

    這篇文章主要介紹了詳解Flutter WebView與JS互相調(diào)用簡易指南,分為JS調(diào)用Flutter和Flutter調(diào)用JS,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-04-04
  • Android系統(tǒng)制作自定義簽名的例子

    Android系統(tǒng)制作自定義簽名的例子

    這篇文章主要介紹了Android系統(tǒng)制作自定義簽名的例子,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Android實(shí)現(xiàn)圖片上傳功能

    Android實(shí)現(xiàn)圖片上傳功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圖片上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Android自定義View實(shí)現(xiàn)左右滑動(dòng)選擇出生年份

    Android自定義View實(shí)現(xiàn)左右滑動(dòng)選擇出生年份

    這篇文章主要介紹了Android自定義View實(shí)現(xiàn)左右滑動(dòng)選擇出生年份,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • 解決Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com

    解決Error:All flavors must now belong to a named flavor dimens

    這篇文章主要介紹了解決Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com,需要的朋友可以參考下
    2017-11-11
  • Android 圖片顯示與屏幕適配的問題

    Android 圖片顯示與屏幕適配的問題

    這篇文章主要介紹了Android 圖片顯示與屏幕適配的問題的相關(guān)資料,Android的分辨率問題是每個(gè)Android 開發(fā)者頭疼的問題,那么這里給大家介紹個(gè)萬能辦法,需要的朋友可以參考下
    2017-08-08
  • 深入了解ViewPager2的使用

    深入了解ViewPager2的使用

    這篇文章主要介紹了ViewPager2 使用的相關(guān)資料,幫助大家更好的進(jìn)行Android開發(fā),感興趣的朋友可以了解下
    2020-12-12
  • 輕松實(shí)現(xiàn)Android仿淘寶地區(qū)選擇功能

    輕松實(shí)現(xiàn)Android仿淘寶地區(qū)選擇功能

    這篇文章主要介紹了輕松實(shí)現(xiàn)Android仿淘寶地區(qū)選擇功能的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評論