2

Note that this is a RuntimeException problem, not the more common IllegalStateException. I have looked in the following questions in Stackoverflow 1, 2 but they gave me no clue how to solve my issue (actually they have none if any answers and the code fragment is not exactly as mine, so I will have hard time to trace the issue as precisely as I did in my case).

So my code it the following:

private var mediaProjection: MediaProjection? = null
private var mediaRecorder: MediaRecorder
private var virtualDisplay: VirtualDisplay? = null
private var width = 567
private var height = 1222

fun startScreenRecording() {
   projectionManager =
        getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
   mediaProjection = projectionManager.getMediaProjection(resultCode, data)?.let {
      initRecorder()
      virtualDisplay = mediaProjection?.createVirtualDisplay(
        "MainScreen", width, height, dpi,
        DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.surface, null, null
      )
      mediaRecorder.start()
   }
}

private fun initRecorder() {
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE)
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
    mediaRecorder.setOutputFile(saveFile)
    mediaRecorder.setVideoSize(width, height)
    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
    mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024)
    mediaRecorder.setVideoFrameRate(30)
    try {
        mediaRecorder.prepare()
    } catch (e: IOException) {
        //TODO handle errors
    }
}

fun stopRecord(): Boolean {
    mediaRecorder.stop()
    mediaRecorder.reset()
    virtualDisplay?.release()
    mediaProjection?.stop()
    return true
}

I am getting the following exception:

java.lang.RuntimeException: Unable to start service com.mobile.android.recorder.screen.RecorderService@3db2c5c with Intent { cmp=com.mobile.android.staging/com.mobile.android.recorder.screen.RecorderService (has extras) }: java.lang.RuntimeException: stop failed.
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3696)
        at android.app.ActivityThread.-wrap21(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1801)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
     Caused by: java.lang.RuntimeException: stop failed.
        at android.media.MediaRecorder._stop(Native Method)
        at android.media.MediaRecorder.stop(MediaRecorder.java:1343)
        at com.mobile.android.recorder.screen.ScreenRecorderUtil.stopRecord(ScreenRecorderUtil.kt:83)
        at com.mobile.android.recorder.screen.RecorderService.stopScreenRecording(RecorderService.kt:117)
        at com.mobile.android.recorder.screen.RecorderService.onStartCommand(RecorderService.kt:90)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3679)
        at android.app.ActivityThread.-wrap21(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1801) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6944) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374) 

Note that the exception happens on the first line of the stopRecord function. It might be that the stacktrace will not make complete sense, but this is because I tried to strip out all unnecessary code complications.

Also note the very weird width and height I have set private var width = 567 private var height = 1222. This is so that I have strongly reproducible error. In my actual code the values are 720 and 1080 and they mostly work, but there are few devices that give me the above error. This said, I am sure the following line is setting the ground for the exception that will be thrown upon stop:

      virtualDisplay = mediaProjection?.createVirtualDisplay(
        "MainScreen", width, height, dpi,
        DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.surface, null, null
      )

The Android documentation of the stop method states:

 * Note that a RuntimeException is intentionally thrown to the
 * application, if no valid audio/video data has been received when stop()
 * is called.

Combining this with what I observe I conclude that the width and height that are supported are device specific and I need to configure correctly so that I get any recording at all. However, I never found any documentation how to determine working pair of width and height for a specific device (e.g. as we do with the preview sizes of camera getSupportedPreviewSizes method of Camera). Can someone advise how to avoid this error?

Boris Strandjev
  • 46,145
  • 15
  • 108
  • 135

0 Answers0