MediaProjection for screen capture - How to change resolution?

1.3k Views Asked by At

Take this block of example code:

// from window manager
val recordWidth = screenWidth
val recordHeight = screenHeight

val projection: MediaProjection = // retrieved from API

val mediaRecorder = MediaRecorder().apply {
    setVideoSource(SURFACE)
    setOutputFormat(MPEG_4)
    setVideoFrameRate(frameRate) // e.g. 30
    setVideoEncoder(H264)
    setVideoSize(recordWidth, recordHeight)
    setVideoEncodingBitRate(videoBitRate)
    setOutputFile(outputFile)
    prepare()
}

val virtualDisplay: VirtualDisplay = projection?.createVirtualDisplay(
        "Example",
        screenWidth,
        screenHeight,
        screenDensity,
        VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
        mediaRecorder.surface,
        null,
        null
)

mediaRecorder.start()

This all works well, as long as screenWidth and screenHeight match that of the display.

If I change recordWidth and recordHeight (which are passed to the MediaRecorder with setVideoSize(Int, Int)), then all goes wrong. The recorded video tends to contain just the upper left section of the overall screen.

So my main questions:

  1. Does something special have to be done to reduce resolution when recording the screen? Even if I keep the aspect ratio with the screen, it doesn't seem to work.
  2. Some width/height values cause a crash - is there an API to retrieve supported screen recording sizes? I know Camera provides one, but this isn't really using the Camera APIs.
1

There are 1 best solutions below

1
On

I think you can refer this one this.mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, resultData);

    Log.d(TAG, "startRecording...");

    this.mVideoBufferInfo = new MediaCodec.BufferInfo();
    MediaFormat mediaFormat = MediaFormat.createVideoFormat(format, width, height);

    mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
    mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, FPS);
    mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 0);
    mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);