MediaRecorder e VideoSource.SURFACE, falha na parada: -1007 (um grave erro no Android)
Estou tentando gravarMediaRecorder
sem utilizarCamera
instância, mas usandoSurface
fonte de vídeo (sim, é possível, mas acabou que não é tão perfeito) -mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
Acabei de escrever qual é o problema:
O código seguinte funciona apenas em alguns dispositivos e funciona temporariamente em alguns dispositivos após a reinicialização recente de um dispositivo ou não funciona de todo
Se não funcionar okMediaRecorder.stop()
método falha com o próximo erro
E / MediaRecorder: falha na parada: -1007 W / System.err:
java.lang.RuntimeException: parada com falha. às
android.media.MediaRecorder.stop (método nativo)
O arquivo mp4 do gravador é muito pequeno (kilobytes) e não pode ser reproduzido
Dispositivos testados:
funciona no Lenovo P2, Xiaomi Mi A1
não funciona no Xiaomi Redmi 5, Sony Xperia, Xiaomi Redmi 4 Prime
Além disso, você pode ler os comentários no meu código para entender melhor o problema
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();
ATUALIZAÇÃO # 1 parece haver algum progresso, qual poderia ser o problema - questão dos códigos (mp4 / h264)
funciona melhor com WEBM / VP8, os vídeos podem ser reproduzidos agora, mas algo errado com o fps, mostra 1000 em propriedades
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.WEBM);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.VP8);
O MediaRecord também não grava áudio ao usar
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.VORBIS);
VerificaO Android MediaRecorder falha ao parar ao usar MP4 / H264 e uma resolução maior que 720p então isso também acontece quando você usaMediaRecorder
eMediaProjection
gravar / capturar a tela do dispositivo (porque também usaSurface
...)
ATUALIZAÇÃO 2 sim parece que o codec vp8 funciona bem, mas um problema para o contêiner webm - SEM ÁUDIO!
O buggy Android simplesmente não suporta codificação de áudio VORBIS / OGG ...https://developer.android.com/guide/topics/media/media-formats#audio-formats