12

I have been trying to figure this out for a while, but for some reason, when I start recording a video with the camera, the preview zooms in. I have the following code from some examples:

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    Camera.Parameters myParameters = mCamera.getParameters();
    List<Camera.Size> sizes = myParameters.getSupportedPreviewSizes();
    Camera.Size myBestSize = getBestPreviewSize(sizes, width, height);

    if (myBestSize != null) {
        myParameters.setPreviewSize(myBestSize.width, myBestSize.height);
        myParameters.setVideoStabilization(false);
        mCamera.setParameters(myParameters);
        mCamera.startPreview();
        mCamera.unlock();
    }
}

private Camera.Size getBestPreviewSize(List<Camera.Size> sizes, int width, int height) {
    final double ASPECT_TOLERANCE = 0.05;
    double targetRatio = (double) width / height;

    if (sizes == null) return null;

    Camera.Size optimalSize = null;

    double minDiff = Double.MAX_VALUE;

    int targetHeight = height;

    // Find size
    for (Camera.Size size : sizes) {
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }

    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;
}

But the preview still zooms in when recording a video. I tried manually setting the preview size to 1280x720, however, it doesn't work on all devices that I tested, with some showing a black SurfaceView.

Is there any way to prevent the preview from zooming in when recording a video? None of the solutions here at StackOverflow seem to work.

EDIT: I tried created a custom SurfaceView with its own onMesaure method, but now I get a -19 error when I start my MediaRecorder. (disregard the -16 in the bounty)

Pink Jazz
  • 784
  • 4
  • 13
  • 34
  • Have you tried checking to see how many times `surfaceChanged` has been called? It might have to do wit the fact that you keep calling `getBestPreviewSize` in a callback method that gets called every time the surface changes..so you'd be stuck in a loop that causes the zoom effect. It seems smarter to call `getBestPreviewSize` in a method like `onMeasure`that actually determines the size of your view – Pztar Sep 02 '16 at 16:23
  • So, are you recommending that I perhaps create a custom view that extends `SurfaceView` with its own `onMeasure` method? Perhaps I can give that a try. – Pink Jazz Sep 02 '16 at 16:28
  • Yes, it seems to make more sense. You should always check that that is in fact the problem, add a `Log.i` to see what the values are being set for `myBestSize.width` and `myBestSize.height` – Pztar Sep 02 '16 at 16:40
  • I tried this, but now my MediaRecorder throws a -19 error when I try to start it. – Pink Jazz Sep 07 '16 at 16:19

2 Answers2

0

I am confused about the kind of zoom you're talking about, could be a software zoom, or the autofocus maybe, so I'll suggest different potential tips leading to the final solution :

  1. Implement mCamera.setZoomChangeListener, eg:

    mCamera.setZoomChangeListener(new Camera.OnZoomChangeListener() {
        @Override public void onZoomChange(int i, boolean b, Camera camera) {
            Log.e("StackOverflow","Zoom just changed !");
            // Inspect things from here
        }
    });
    
  2. Disable the smooth zoom :

    mCamera.stopSmoothZoom(); // My device doesn't support it, but maybe your device does
    
  3. Inspect all of yours Camera.Parameters:

    Log.e("StackOverflow", "All Camera parameters :");
    for(String s : mCamera.getParameters().flatten().split(";"))
        Log.e("StackOverflow", s + "\n");
    
  4. Then switch anything that could be zoom related, eg :

    Camera.Parameters parameters = mCamera.getParameters();
    parameters.setZoom(100); // My device support some values in the range 100 | 400
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
    parameters.setVideoStabilization(false);
    
    // Don't forget to add the new parameters to the camera :
    mCamera.setParameters(parameters);
    

Regards

J.Jacobs
  • 703
  • 6
  • 17
0

You probably have setVideoStabilization(true). In high res e.g. 4K, if you enable this, it will create this jump zoom.

Diolor
  • 13,181
  • 30
  • 111
  • 179