Android MediaRecorder crashes on stop when using MP4/H264 and a resolution bigger than 720p

时光怂恿深爱的人放手 提交于 2019-11-29 23:24:25

问题


I´m trying to write a screen recorder for android and i use this as base: https://github.com/commonsguy/cw-omnibus/tree/master/MediaProjection/andcorder

My problem is: If i select a resolution bigger than 720p with mp4/h264 settings, it crashes on stop.

Examples:

(Example 1) Does NOT work

Code in RecordingSession.java:

  void start() {
    recorder=new MediaRecorder();
    recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    recorder.setVideoFrameRate(config.frameRate);
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    recorder.setVideoSize(1080, 1920);
    recorder.setVideoEncodingBitRate(config.bitRate);
    recorder.setOutputFile(output.getAbsolutePath());

    try {
      recorder.prepare();
      vdisplay=projection.createVirtualDisplay("andcorder",
              1080, 1920, config.density,
        VIRT_DISPLAY_FLAGS, recorder.getSurface(), null, null);
      beeper.startTone(ToneGenerator.TONE_PROP_ACK);
      recorder.start();
    }
    catch (IOException e) {
      throw new RuntimeException("Exception preparing recorder", e);
    }
  }

Output on stop:

07-29 13:52:32.880 7845-7845/com.commonsware.android.andcorder E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                 Process: com.commonsware.android.andcorder, PID: 7845
                                                                                 java.lang.RuntimeException: Unable to start service com.commonsware.android.andcorder.RecorderService@61a260a with Intent { act=com.commonsware.android.andcorder.STOP flg=0x10000000 cmp=com.commonsware.android.andcorder/.RecorderService bnds=[257,1321][832,1513] }: java.lang.RuntimeException: stop failed.
                                                                                     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3045)
                                                                                     at android.app.ActivityThread.access$2200(ActivityThread.java:157)
                                                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1454)
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                     at android.os.Looper.loop(Looper.java:148)
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:5525)
                                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
                                                                                  Caused by: java.lang.RuntimeException: stop failed.
                                                                                     at android.media.MediaRecorder.native_stop(Native Method)
                                                                                     at android.media.MediaRecorder.stop(MediaRecorder.java:851)
                                                                                     at com.commonsware.android.andcorder.RecordingSession.stop(RecordingSession.java:84)
                                                                                     at com.commonsware.android.andcorder.RecorderService.stopRecorder(RecorderService.java:152)
                                                                                     at com.commonsware.android.andcorder.RecorderService.onStartCommand(RecorderService.java:72)
                                                                                     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3028)
                                                                                     at android.app.ActivityThread.access$2200(ActivityThread.java:157) 
                                                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1454) 
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                     at android.os.Looper.loop(Looper.java:148) 
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:5525) 
                                                                                     at java.lang.reflect.Method.invoke(Native Method) 
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 

(Example 2) - works fine

Code:

  void start() {
    recorder=new MediaRecorder();
    recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    recorder.setVideoFrameRate(config.frameRate);
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    recorder.setVideoSize(720, 1280);
    recorder.setVideoEncodingBitRate(config.bitRate);
    recorder.setOutputFile(output.getAbsolutePath());

    try {
      recorder.prepare();
      vdisplay=projection.createVirtualDisplay("andcorder",
              720, 1280, config.density,
        VIRT_DISPLAY_FLAGS, recorder.getSurface(), null, null);
      beeper.startTone(ToneGenerator.TONE_PROP_ACK);
      recorder.start();
    }
    catch (IOException e) {
      throw new RuntimeException("Exception preparing recorder", e);
    }
  }

(Example 3) - also works fine

  void start() {
    recorder=new MediaRecorder();
    recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.WEBM);
    recorder.setVideoFrameRate(config.frameRate);
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.VP8);
    recorder.setVideoSize(1080, 1920);
    recorder.setVideoEncodingBitRate(config.bitRate);
    recorder.setOutputFile(output.getAbsolutePath());

    try {
      recorder.prepare();
      vdisplay=projection.createVirtualDisplay("andcorder",
              1080, 1920, config.density,
        VIRT_DISPLAY_FLAGS, recorder.getSurface(), null, null);
      beeper.startTone(ToneGenerator.TONE_PROP_ACK);
      recorder.start();
    }
    catch (IOException e) {
      throw new RuntimeException("Exception preparing recorder", e);
    }
  }

As you can see, i can record in 1080p (and any other resolution over 720p) using webm/vp8, but not using mp4/h264. Than you may ask: Why are you not using webm, it works! Because of this:

http://i.imgur.com/E9N3p6e.png

Look at the red marked fields. Webm doesn´t save video´s length, frame- and bitrate. Also i got problems recording audio within webm. I would like to use mp4/h264, but it fails on resolutions higher than 720p. Any solution?

EDIT: My test-device is a LG G4 / Android 6.0

来源:https://stackoverflow.com/questions/38658485/android-mediarecorder-crashes-on-stop-when-using-mp4-h264-and-a-resolution-bigge

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!