Android5.0免Root截屏,錄屏

來源:互聯網
上載者:User

標籤:position   track   pre   編解碼   解碼器   file      callback   and   

http://blog.csdn.net/wds1181977/article/details/52174840

MediaProjection介紹

MediaProjection可以用來捕捉螢幕,具體來說可以截取當前螢幕和錄製螢幕視頻。MediaProjection由MediaProjectionManager來管理和擷取。

使用步驟

首先擷取MediaProjectionManager,和其他的Manager一樣通過 Context.getSystemService() 傳入參數MEDIA_PROJECTION_SERVICE獲得執行個體。

接著調用MediaProjectionManager.createScreenCaptureIntent()彈出dialog詢問使用者是否授權應用捕捉螢幕,同時覆寫onActivityResult()擷取授權結果。

如果授權成功,通過MediaProjectionManager.getMediaProjection(int resultCode, Intent resultData)擷取MediaProjection執行個體,通過MediaProjection.createVirtualDisplay(String name, int width, int height, int dpi, int flags, Surface surface, VirtualDisplay.Callback callback, Handler handler)建立VirtualDisplay執行個體。實際上在上述方法中傳入的surface參數,是真正用來截屏或者錄屏的。

截屏

截屏這裡用到ImageReader類,這個類的getSurface()方法擷取到surface直接傳入MediaProjection.createVirtualDisplay()方法中,此時就可以執行截取。通過ImageReader.acquireLatestImage()方法即可擷取當前螢幕的Image,經過簡單處理之後即可儲存為Bitmap。

           private void startCapture() {            mImageName = System.currentTimeMillis() + ".png";            Log.e(TAG, "image name is : " + mImageName);            Image image = mImageReader.acquireLatestImage();            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);            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);            image.close();            if (bitmap != null) {                Log.e(TAG, "bitmap  create success ");                try {                    File fileFolder = new File(mImagePath);                    if (!fileFolder.exists())                        fileFolder.mkdirs();                    File file = new File(mImagePath, mImageName);                    if (!file.exists()) {                        Log.e(TAG, "file create success ");                        file.createNewFile();                    }                    FileOutputStream out = new FileOutputStream(file);                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);                    out.flush();                    out.close();                    Log.e(TAG, "file save success ");                    Toast.makeText(this.getApplicationContext(), "成功", Toast.LENGTH_SHORT).show();                } catch (IOException e) {                    Log.e(TAG, e.toString());                    e.printStackTrace();                }            }        }
錄屏

錄屏需要用到上篇博文中的MediaCadec,這個類將原始的螢幕資料編碼,在通過MediaMuxer分裝為mp4格式儲存。MediaCodec.createInputSurface()擷取一個surface對象講起傳入MediaProjection.createVirtualDisplay()即可擷取螢幕原始多媒體資料,之後讀取MediaCodec編碼輸出資料經過MediaMuxer封裝處理為mp4即可播放,實現錄屏。

       private void recordVirtualDisplay() {//迴圈多去轉碼器輸出資料經過處理儲存為mp4        while (!mIsQuit.get()) {            int index = mMediaCodec.dequeueOutputBuffer(mBufferInfo, 10000);            Log.i(TAG, "dequeue output buffer index=" + index);            if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {//後續輸出格式變化                resetOutputFormat();            } else if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {//請求逾時                Log.d(TAG, "retrieving buffers time out!");                try {                    // wait 10ms                    Thread.sleep(10);                } catch (InterruptedException e) {                }            } else if (index >= 0) {//有效輸出                if (!mMuxerStarted) {                    throw new IllegalStateException("MediaMuxer dose not call addTrack(format) ");                }                encodeToVideoTrack(index);                mMediaCodec.releaseOutputBuffer(index, false);            }        }    }        private void encodeToVideoTrack(int index) {//輸出資料為mp4檔案        ByteBuffer encodedData = mMediaCodec.getOutputBuffer(index);        if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {//是特定格式資訊等配置資料,不是媒體資料            // The codec config data was pulled out and fed to the muxer when we got            // the INFO_OUTPUT_FORMAT_CHANGED status.            // Ignore it.            Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG");            mBufferInfo.size = 0;        }        if (mBufferInfo.size == 0) {            Log.d(TAG, "info.size == 0, drop it.");            encodedData = null;        } else {            Log.d(TAG, "got buffer, info: size=" + mBufferInfo.size                    + ", presentationTimeUs=" + mBufferInfo.presentationTimeUs                    + ", offset=" + mBufferInfo.offset);        }        if (encodedData != null) {//存在編碼資料            encodedData.position(mBufferInfo.offset);            encodedData.limit(mBufferInfo.offset + mBufferInfo.size);            mMuxer.writeSampleData(mVideoTrackIndex, encodedData, mBufferInfo);//寫入            Log.i(TAG, "sent " + mBufferInfo.size + " bytes to muxer...");        }    }        private void resetOutputFormat() {        // should happen before receiving buffers, and should only happen once        if (mMuxerStarted) {            throw new IllegalStateException("output format already changed!");        }        MediaFormat newFormat = mMediaCodec.getOutputFormat();        Log.i(TAG, "output format changed.\n new format: " + newFormat.toString());        mVideoTrackIndex = mMuxer.addTrack(newFormat);        mMuxer.start();        mMuxerStarted = true;        Log.i(TAG, "started media muxer, videoIndex=" + mVideoTrackIndex);    }
附錄參考

官方文檔

Android視頻錄製

Android 5.0截屏

Android錄屏代碼 
本文Demo

  

Android5.0免Root截屏,錄屏

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.