2017年4月4日 星期二

android5.0以上,用MediaProjection API 錄製螢幕畫面




上一篇說到Android 手機不用root,要如何捕抓螢幕,這次講要如何錄製,跟上一篇幾乎一樣,捕捉螢幕是得到ImageRecorder,錄製畫面改成MediaRecorder就可以,但要先初始化這個MediaRecorder,我把它放在這個init_media_recorder()只是設定一些資訊,但AndroidManifest記得給android.permission.RECORD_AUDIO權限,mMediaRecorder.prepare();準備完mMediaRecorder.start();就開始錄製了,記得VirtualDisplay放在onActivityResult method是較正確的,上篇有說到為什麼.

錄製畫面,其實很簡單,看網路上的例子繞來繞去,真不好搞懂,我把它整理一下很容易看懂,上面影片,就是用MediaProjection API錄製的,畫面很好,聲音不知為什很差,可能是解碼器的關係,這我就不曉得了,應該是透過麥克風錄音的關係!!


    private MediaProjectionManager mpm;
    private MediaProjection mp;
    private VirtualDisplay vp_recorder=null;//recorder screen
    private MediaRecorder mMediaRecorder;
    //private static final int REQUEST_NUMBER=1001;
    private static final int REQUEST_NUMBER=1;



     mMediaRecorder=new MediaRecorder();  //
  mpm=(MediaProjectionManager)getSystemService(MEDIA_PROJECTION_SERVICE); //media projection manager
     startActivityForResult(mpm.createScreenCaptureIntent(),REQUEST_NUMBER); //開始授權media projection



    @Override
    public void onActivityResult(int requestCode,int resultCode,Intent data){

        if(REQUEST_NUMBER==requestCode) {
            if (resultCode != RESULT_OK) {
                Toast.makeText(this, "USER CANCELLED", Toast.LENGTH_LONG).show();
                return;
            }
            DisplayMetrics ds = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(ds);
            int dpi = ds.densityDpi;
            int dw = ds.widthPixels;
            int dh = ds.heightPixels;
            mp = mpm.getMediaProjection(resultCode, data);
            //B.螢幕錄製,AndroidManifest記得給android.permission.RECORD_AUDIO
            if (vp_recorder == null) {//只是確保一個virtual display
                //mMediaRecorder = new MediaRecorder();                                     //這個螢幕錄製,這個和capture screen不相干
                init_media_recorder();             //初始化media recorder
                prepare_media_recorder();      //準備錄製
                //建立虛擬display for recorder screen
                vp_recorder = mp.createVirtualDisplay("ScreenRecorder", dw, dh, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null, null);

            }

        }
    }



//////////////////////////////recorder screen////////////////////////////////////////////////////////////////////

    public void start_Recorder(View v){
        //init_media_recorder();         //初始化media recorder
        //prepare_media_recorder();      //準備錄製
        mMediaRecorder.start();        //開始錄製
        this.moveTaskToBack(true);   //app退到後台
    }
    public void stop_Recorder(View v){
        mMediaRecorder.stop();         //停止錄製
        mMediaRecorder.reset();
        this.show_app();
    }

    //初始化media recorder,AndroidManifest記得給android.permission.RECORD_AUDIO
    private void init_media_recorder() {
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);    //音源
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);//影源
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//格式
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);  //影像解碼器
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//音源解碼器
        mMediaRecorder.setVideoEncodingBitRate(512*1000);                 //解碼率
        mMediaRecorder.setVideoFrameRate(30);                             //視窗更新頻率
        mMediaRecorder.setVideoSize(480,640);                             //影像寬高
        mMediaRecorder.setOutputFile("/sdcard/capture.mp4");              //儲存路徑
    }
//準備錄製
    private void prepare_media_recorder(){
        try {
            mMediaRecorder.prepare();
        }
        catch(Exception e)
        {
            e.printStackTrace();
            finish();
        }
    }


沒有留言: