title: Android MediaRecorder aspect ratio incorrect
body: <p>I'm having issues with the aspect ratio of a MediaRecorder in my Android app.  I'm having the issue specifically with the Samsung Galaxy S II, whose video camera seems to zoom in compared to the regular camera (this is a behavior I notice when using the default camera app on the phone as well).</p>
  
  <p>You can see how the aspect ratio is stretched when I switch from using the camera to using the MediaRecorder in this video:</p>
  
  <p><a href="https://www.youtube.com/watch?v=U8vCwiNjCPU" rel="nofollow noreferrer">https://www.youtube.com/watch?v=U8vCwiNjCPU</a></p>
  
  <p>and in the screenshots below:</p>
  
  <p><strong>Camera aspect ratio (correct):</strong> </p>
  
  <p><img src="https://i.stack.imgur.com/l09bC.png" alt="Camera aspect ratio"></p>
  
  <p><strong>Video aspect ratio (incorrect):</strong> </p>
  
  <p><img src="https://i.stack.imgur.com/laBJK.png" alt="Video aspect ratio"></p>
  
  <p><strong>How can I ensure that the aspect ratio of the video preview is correct?</strong></p>
  
  <p>Here is my code:</p>
  
  <p><strong>CustomCamera activity:</strong></p>
  
  <pre><code>public class CustomCamera extends SherlockActivity {
  
  private boolean prepareVideoRecorder() {
          Log.d(TAG, "in prepareVideoRecorder()");
          // It is very important to unlock the camera before doing setCamera
          // or it will results in a black preview
          if (camera == null) 
          {
              camera = getCameraInstance();
          }
  
          if (recorder == null){
              recorder = new MediaRecorder();
          }
  
          //Have to stop preview before starting to record
          camera.stopPreview();
          // Step 1: Unlock and set camera to MediaRecorder
          camera.unlock();
          recorder.setCamera(camera);
  
          // Step 2: Set sources
          recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
          recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
  
          // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
          recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
  
          // Step 4: Set output file
          recorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).getAbsolutePath());
  
          // No limit. Don't forget to check the space on disk.
          recorder.setMaxDuration(50000);
          recorder.setVideoFrameRate(30);
          recorder.setVideoEncodingBitRate(3000000);
          recorder.setAudioEncodingBitRate(8000);
  
          // Step 5: Set the preview output
          recorder.setPreviewDisplay(cameraPreview.getHolder().getSurface());
  
          //Setting the camera's orientation
          int degree = 0;
          // do not rotate image, just put rotation info in
          switch (mOrientation) {
          case ORIENTATION_LANDSCAPE_INVERTED:
              degree = 180;
              break;
          case ORIENTATION_PORTRAIT_NORMAL:
              degree = 90;
              break;
          case ORIENTATION_LANDSCAPE_NORMAL:
              degree = 0;
              break;
          case ORIENTATION_PORTRAIT_INVERTED:
              degree = 270;
              break;
          }
  
          recorder.setOrientationHint(degree);
  
          // Step 6: Prepare configured MediaRecorder
          try {
              recorder.prepare();
          } catch (IllegalStateException e) {
              // This is thrown if the previous calls are not called with the
              // proper order
              e.printStackTrace();
              releaseMediaRecorder();
              return false;
          } catch (IOException e) {
              releaseMediaRecorder();
              e.printStackTrace();
              return false;
          }        
          //Everything went successfully
          return true;
      }
  
  
  }
  
      /**
       * Method used to set the camera preview's parameters to match the
       * phone's width and set the height accordingly to assure that there are
       * no aspect ratio issues.
       */
      private void setHolderParameters() {
          Log.d(TAG, "setting camera layout parameters");
          DisplayMetrics metrics = new DisplayMetrics();
          getWindowManager().getDefaultDisplay().getMetrics(metrics);
  
          int height = metrics.heightPixels;
          int width = metrics.widthPixels;
  
          Size mPreviewSize = CameraPreview.getOptimalPreviewSize(camera.getParameters().getSupportedPreviewSizes(), width, height);
          double ratio = ((double)mPreviewSize.width)/mPreviewSize.height;
  
          FrameLayout.LayoutParams previewParams = new FrameLayout.LayoutParams(width, (int)(width*ratio));
  
          cameraPreview.setLayoutParams(previewParams);       
      }
  
      /**
       * Open the camera asynchronously to reduce the lag when opening
       * activity
       */
      public void openCameraAsync(){
          new AsyncTask&lt;Object, Object, Object&gt;(){
              @Override
              protected Object doInBackground(Object... arg0) {
                  if (!isFinishing()){
                      //Resuming camera and display when resuming
                      if(camera == null){
                          Log.d(TAG, "Resuming with a null camera");
                          camera = getCameraInstance();
                      }
                  }
                  return null;
              }
  
              @Override
              protected void onPostExecute(Object result){
                  setHolderParameters();
                  cameraPreview.setCamera(camera);
  
                  //Calling surface created so that the preview of the camera is correct
                  cameraPreview.surfaceCreated(cameraPreview.getHolder());
              }
          }.execute();
      }
  </code></pre>
  
  <p><strong>CameraPreview.java:</strong></p>
  
  <pre><code>public static Size getOptimalPreviewSize(List&lt;Size&gt; sizes, int w, int h) {
          Log.d(TAG, "getOptimalPreviewSize");
          final double ASPECT_TOLERANCE = 0.05;
          double targetRatio = (double) w/h;
  
          if (sizes==null) return null;
  
          Size optimalSize = null;
  
          double minDiff = Double.MAX_VALUE;
  
          int targetHeight = h;
  
          // Find size
          for (Size size : sizes) {
              double ratio = (double) size.width / size.height;
              if (Math.abs(ratio - targetRatio) &gt; ASPECT_TOLERANCE) continue;
              if (Math.abs(size.height - targetHeight) &lt; minDiff) {
                  optimalSize = size;
                  minDiff = Math.abs(size.height - targetHeight);
              }
          }
  
          if (optimalSize == null) {
              minDiff = Double.MAX_VALUE;
              for (Size size : sizes) {
                  if (Math.abs(size.height - targetHeight) &lt; minDiff) {
                      optimalSize = size;
                      minDiff = Math.abs(size.height - targetHeight);
                  }
              }
          }
          Log.d(TAG, "targetRatio: " + targetRatio);
          Log.d(TAG, "optimalSize: " + optimalSize);
          return optimalSize;
      }
  
      public void setRecorder(MediaRecorder recorder){
          this.recorder = recorder;
      }
  </code></pre>