Android MediaRecorder saving empty file and weird camera behaviours

673 views Asked by At

I am having a headache over the Camera API 1 for android. After reading all of the Internet content, I made some sample app that works OK. It creates a service, which then is used to operate with the camera in the background, so there is no preview or activity enabled. To achieve this I use a dummy SurfaceHolder, like this:

protected class MySurfaceHolder implements SurfaceHolder {
        private final Surface surface;
        private final SurfaceTexture surfaceTexture;

        public MySurfaceHolder () {
            int[] textures = new int[1];
            GLES20.glGenTextures(1, textures, 0);

            if (textures.length > 0) {
                this.surfaceTexture = new SurfaceTexture(textures[0]);
                this.surface = new Surface(this.surfaceTexture);
            } else {
                this.surface = null;
                this.surfaceTexture = null;
            }
        }

        [...]
}

and then I use it like this

    // simplified version of my code
    try {
        initializeCamera(); // open camera and set Camera.Parameters

        camera.setPreviewDisplay(new MySurfaceHolder());
        camera.startPreview();
        camera.unlock();

        initializeMediaRecorder(); // create MediaRecorder, set video/audio parameters

        mediaRecorder.prepare();
        mediaRecorder.start();
        // wait until recording finish and exit
    } finally {
        stopRecording();
    }

the Camera and MediaRecorder initialization methods are just like the documentation states they should be (and they work).

Everything works and operates as it should. Almost everything - sometimes, under unknown circumstances the MediaRecorder creates empty files, like 32kB containing only headers and info about the video - no frames. The longer I record like this, the bigger is the file (few kB every few seconds). After 1 minute, the file weights about 80kB. Funny thing is I know that the camera is working and capturing frames (I debugged it a little showing preview frames), but the frames are not written into the output file.

Also when it happens I am not able to record in FHD (1920x1080) - I get the "start failed" message - at this time camera is not capturing frames. The same thing could happen when I use wrong (not supported) video size. I suppose in this case the message is thrown at the mediaRecorder.start(); line, and stopRecording(); is invoked but I am not sure.

After some time or after unknown action the problem is suddenly gone (I don't know when, I don't know how). It happens for sure on Android 5.1, but may happen on other versions as well.

  1. Could this bug be related to my custom surface code?
  2. What could cause the MediaRecorder to not write frames into a file?
  3. Why I am not able to record in FHD, but in the same time I am able to record in HD (1280x720)?
  4. Is there any alternative for MediaRecorder, so I can avoid these bugs?
  5. May it happen when another app is trying to get Camera object, thus distrupting current recording? If so, how to regain access to the Camera object (I apparently am not able to do this now on some devices).

EDIT:

I think I might have a clue. I am calling

camera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
    // ... get current frame
}
camera.startPreview();

to get preview frame of current recording. It appears that the bug occurs when I am using this method to get preview frame (at random times). It seems flawed, because not all devices react to this thing properly (sometimes there is no preview frame...). Is there any other, better method of handling current preview frame without the real surface?

0

There are 0 answers