MediaRecorder and VideoSource.SURFACE, stop failed: -1007 (a serious Android bug)

android, android-canvas, android-mediarecorder, mediarecorder, surface

Solution

I guess there is no solution

so the answer: MediaRecorder/Android is buggy or Mobile companies didn't care of all Android features while developing their devices

Update

`MediaCodec` is also buggy with canvas

mSurface = mMediaCodec.createInputSurface();
mSurface.lockHardwareCanvas()

It works on most devices with `MediaCodec` but still some devices may fail to record video correctly using this method

So final answer: don't ever use `lockCanvas` or `lockHardwareCanvas` when working with `MediaCodec` or `MediaRecorder`, it's buggy.. At least on old phones, newer Android versions I guess should work fine

The only way - OpenGl ES

other links about issue:

https://github.com/googlesamples/android-Camera2Video/issues/86 https://issuetracker.google.com/issues/111433520

Problem

I'm trying to record `MediaRecorder` without using `Camera` instance but using `Surface` video source (yes it's possible, but it turned out that it's not that perfect) - `mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);` I just write what the issue: Next code works only on some devices and works temporary on some devices after a recent device rebooting or doesn't work at all If it doesn't work ok `MediaRecorder.stop()` method fails with the next error E/MediaRecorder: stop failed: -1007 W/System.err: java.lang.RuntimeException: stop failed. at android.media.MediaRecorder.stop(Native Method) recorder mp4 file is too small size (kilobytes) and it can't be played Tested devices: works on Lenovo P2, Xiaomi Mi A1 doesn't work on Xiaomi Redmi 5, Sony Xperia, Xiaomi Redmi 4 Prime Also you can read comments in my code to understand the issue better ``` new Thread(() -> { MediaRecorder mediaRecorder = new MediaRecorder(); File file = new File(Environment.getExternalStorageDirectory() + File.separator + "test_media_recorder_surface_source.mp4"); if (file.exists()) { file.delete(); } mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mediaRecorder.setOutputFile(file.getAbsolutePath()); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mediaRecorder.setVideoSize(1280, 720); mediaRecorder.setCaptureRate(24); try { mediaRecorder.prepare(); int sleepTime = 1000 / 24; Surface surface = mediaRecorder.getSurface(); mediaRecorder.start(); // record something (we can also record frames here from onPreviewFrame byte arrays) // e.g. convert raw frame byte[] to Bitmap using mb OpenCV and then draw bitmap on canvas // using canvas.drawBitmap(...) // here we record just blue background... for (int i = 0; i < 120; i++) { // 5 seconds, 24 fps Canvas canvas = surface.lockCanvas(null); canvas.drawColor(Color.BLUE); surface.unlockCanvasAndPost(canvas); try { Thread.sleep(sleepTime); } catch (InterruptedException e) { e.printStackTrace(); } } // on many devices stop fails with RuntimeException -1007 error code // I guess it works ok 100% only for modern powerful devices... mediaRecorder.stop(); // E/MediaRecorder: stop failed: -1007 // W/System.err: java.lang.RuntimeException: stop failed. // at android.media.MediaRecorder.stop(Native Method) // recorder.reset(); mediaRecorder.release(); // I get file with very small size (kilobytes) and it can't be played // ######## RESULTS ###### // WORKS OK ON: // - Lenovo P2 (Android 7) // - Xiaomi Mi A1 (Android 8) // DOESN'T WORK ON (stop fails with -1007, small video file and can't be played): // - Xiaomi Redmi 5 (Android 7) // - Sony Xperia (I don't remember the exact model and Android OS) // - Xiaomi Redmi 4 Prime (Android 6) * // * p.s. on Xiaomi Redmi 4 Prime it works some time after rebooting the device // if I leave this smartphone for a while and try again it will fail again // until I reboot the device... } catch (Exception e) { e.printStackTrace(); } }).start(); ``` UPDATE #1 seems some progress what could be the issue - codes issue (mp4/h264) it works better with WEBM/VP8, videos can be played now, but something wrong with fps, it shows 1000 in proporties ``` mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.WEBM); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.VP8); ``` also MediaRecord doesn't record audio when using ``` mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.VORBIS); ``` check Android MediaRecorder crashes on stop when using MP4/H264 and a resolution bigger than 720p so it also happens when you use `MediaRecorder` and `MediaProjection` to record/capture device Screen (because it also uses `Surface`...) UPDATE 2 yes seems vp8 codec works fine, but one problem for webm container - NO AUDIO! buggy Android just doesn't support VORBIS/OGG audio encoding... https://developer.android.com/guide/topics/media/media-formats#audio-formats

Original source

Related problems