0

I'm trying to make a custom camera activity. Everything works great until the MediaRecorder starts recording a video. The preview stretches horizontally without an obvious reason as below. I have tried changing the preview size and several suggestions but I couldn't find a working solution. Any Ideas please !!

note: I'm using TextureView object.

preview before recording preview before recording

preview while recording preview while recording

start camera

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
    mST = surface;
    try {
        mCamera.setDisplayOrientation(90);
        mCamera.setPreviewTexture(mST);
        mCamera.startPreview();
        isReleased = false;
    }catch(Exception e){}
    //startVideoPreview();
}

start media recorder

private boolean prepareMediaRecorder() {
    mediaRecorder = new MediaRecorder();
    mCamera.unlock();
    mediaRecorder.setCamera(mCamera);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setProfile(CamcorderProfile.get(camId, CamcorderProfile.QUALITY_TIME_LAPSE_HIGH));
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);
    mediaRecorder.setMaxDuration(30000); //set maximum duration 60 sec.
    mediaRecorder.setMaxFileSize(50000000); //set maximum file size 50M
    mediaRecorder.setPreviewDisplay(new Surface(mTextureView.getSurfaceTexture()));
    mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory() + "/tempVid.mp4");



    if(camId == Camera.CameraInfo.CAMERA_FACING_BACK){
        mediaRecorder.setOrientationHint(90);
    }else{
        mediaRecorder.setOrientationHint(270);
    }
    try {
        mediaRecorder.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        releaseMediaRecorder();
        return false;
    }
    return true;
}

thank you so much

abdulrahman
  • 35
  • 1
  • 6

1 Answers1

0

There are two issues with your app.

One, you should choose preview size that suits you. Your code in onSurfaceTextureAvailable() relies on default, which is too optimistic. Some devices have weird defaults for preview size. Especially when you want live preview displayed on a surface. You should choose the optimal preview size (from the list returned by Parameters.getSupportedPreviewSizes()). The optimal size will be the best to fit the given width and height. The most important factor is aspect ratio. But also, you also want the preview not to be too small or too big. You can pick up a simple example of getBestPreviewSize ().

The second issue is that MediaRecorder also sets the 'preview' size. Each CamcorderProfile defines a specific frame size, and when you choose it, the live preview on your screen changes accordingly. You can override this with MediaRecorder.setVideoSize(), but if this size does not fit the chosen CamcorderProfile, your recording may be spoiled.

Not all supported preview sizes may be used for video recording, (see Parameters.getSupportedVideoSizes()). So, if you open preview with intention to record video, you should choose an optimal preview size that can be used by MediaRecorder, and make sure you set both Camera and MediaRecorder this way.

Finally, note that you are working with a deprecated Camera API. If your target device is Lollipop and above, consider switching to camera2 API.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307