關於Android錄屏並推流

1.主要流程

2.關於開源項目:ScreenRecorder

  • 在界面中獲取所有可配置的信息EncodeConfig(MediaCodec,MediaMuxer都會使用)
  • 主要方法:
    獲取MediaProjectionManager實例
mMediaProjectionManager = (MediaProjectionManager) getApplicationContext().getSystemService(MEDIA_PROJECTION_SERVICE);
  • 錄屏授權
 Intent captureIntent = mMediaProjectionManager.createScreenCaptureIntent();
 startActivityForResult(captureIntent, REQUEST_MEDIA_PROJECTION);
  • 授權後獲取實例
MediaProjection mediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);
VirtualDisplay virtualDisplay  = mediaProjection.createVirtualDisplay("ScreenRecorder-display0",
                    config.width, config.height, 1 /*dpi*/,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,
                    null /*surface*/, null, null);
mVirtualDisplay.setSurface(mVideoEncoder.getInputSurface());
  • 創建封包器並丟數據進出
mMuxer = new MediaMuxer(mDstPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
writeSampleData(mVideoTrackIndex, buffer, encodedData);
  • 通過MediaCodec獲取h264數據
MediaFormat format = createMediaFormat();
        Log.d("Encoder", "Create media format: " + format);

        String mimeType = format.getString(MediaFormat.KEY_MIME);
        final MediaCodec encoder = createEncoder(mimeType);
        try {
            if (this.mCallback != null) {
                // NOTE: MediaCodec maybe crash on some devices due to null callback
                encoder.setCallback(mCodecCallback);
            }
            encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
            onEncoderConfigured(encoder);
            encoder.start();
        } catch (MediaCodec.CodecException e) {
            Log.e("Encoder", "Configure codec failure!\n  with format" + format, e);
            throw e;
        }
  • MediaCodec 運行狀態,編碼後的數據通過回掉返回
 /**
     * let media codec run async mode if mCallback != null
     */
    private MediaCodec.Callback mCodecCallback = new MediaCodec.Callback() {
        @Override
        public void onInputBufferAvailable(MediaCodec codec, int index) {
            mCallback.onInputBufferAvailable(BaseEncoder.this, index);
        }

        @Override
        public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) {
            mCallback.onOutputBufferAvailable(BaseEncoder.this, index, info);
        }

        @Override
        public void onError(MediaCodec codec, MediaCodec.CodecException e) {
            mCallback.onError(BaseEncoder.this, e);
        }

        @Override
        public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
            mCallback.onOutputFormatChanged(BaseEncoder.this, format);
        }
    };
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章