Dennis Schiepers
Dennis Schiepers

Reputation: 137

Android Camera2 API - Video always saved in landscape

I am working on a video recording app in which I want to record videos in portrait. Everything seems fine except for the video which is saved in landscape mode. I tried the implementation using this project: https://github.com/HofmaDresu/AndroidCamera2Sample as an example, but still, the video is being saved in landscape mode.

   void PrepareMediaRecorder()
    {
        if (mediaRecorder == null)
        {
            mediaRecorder = new MediaRecorder();
        }
        else
        {
            mediaRecorder.Reset();
        }

        var map = (StreamConfigurationMap)characteristics.Get(CameraCharacteristics.ScalerStreamConfigurationMap);
        if (map == null)
        {
            return;
        }

        videoFileName = GetVideoFilePath();

        mediaRecorder.SetAudioSource(AudioSource.Mic);
        mediaRecorder.SetVideoSource(VideoSource.Surface);
        mediaRecorder.SetOutputFormat(OutputFormat.Mpeg4);
        mediaRecorder.SetOutputFile(videoFileName);
        mediaRecorder.SetVideoEncodingBitRate(10000000);
        mediaRecorder.SetVideoFrameRate(30);
        var videoSize = ChooseVideoSize(map.GetOutputSizes(Java.Lang.Class.FromType(typeof(MediaRecorder))));
        mediaRecorder.SetVideoEncoder(VideoEncoder.H264);
        mediaRecorder.SetAudioEncoder(AudioEncoder.Aac);
        mediaRecorder.SetVideoSize(videoSize.Width, videoSize.Height);
        int rotation = (int)Activity.WindowManager.DefaultDisplay.Rotation;
        mediaRecorder.SetOrientationHint(GetOrientation(rotation));
        mediaRecorder.Prepare();
    }

Upvotes: 0

Views: 291

Answers (1)

Eddy Talvala
Eddy Talvala

Reputation: 18107

Assuming a high-quality video player shows you the video in portrait (if not, your GetOrientation method probably has an error in it), but other players you still care about are stuck on landscape:

You'll have to rotate the frames yourself. Unfortunately, this is messy, since there's no automatic control for this on the media encoder APIs that I know of.

Options are receiving frames via an ImageReader from the camera, and then doing the rotation in Java or via JNI, in native code, and then sending the frame to the encoder either via an ImageWriter to a MediaRecorder or MediaCodec Surface, or writing frames via MediaCodec's ByteBuffer interface.

Or you could send the frames to the GPU via a SurfaceTexture, rotate in a fragment shader, and then write out to a Surface tied to a MediaRecorder/MediaCodec again.

Both of these require a lot of boilerplate code and understanding of lower-level details, unfortunately.

Upvotes: 2

Related Questions