Search code examples
androidandroid-layoutandroid-orientation

Detecting if video was taken in portrait/landscape


I would like to confirm that what I am doing is indeed the correct way as some elements behave unexpected.

First, I have a landscape and portrait layout, as I understand, doing this will automatically detect if the phone is in portrait/landscape mode:

- layout
   - activity_video_player.xml
 - layout-land
   - activity_video_player.xml

Then when the user selects a video from the gallery, I check if the video was taking in landscape or portrait, by doing this (inside OnCreate):

int w;
int h;

MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(this, videoURI);
String height = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
String width = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
w = Integer.parseInt(width);
h = Integer.parseInt(height);

if (w > h) {  
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

I have tested this and it works fine, but I noticed some of my xml elements (play button) is placed incorrectly.

So my app flow is:

MainActivity --> SelectvidButton --> Gallery Intent --> VideoPlayActivity

My Question

Is this the correct way of doing this and if it is, is there any reason why some of the xml elements get placed incorrectly?


EDIT 1:

I noticed that this only happens when the activity is launched for the first time, if I press the back button and select the same video again, the layout is perfectly like I want it to be.


EDIT 2:

I have also noticed that this only happens if the previous activity (MainActivity) was in the same orientation than what the selected video is.


Solution

  • Here is what I ended up doing.

    Instead of using MediaMetadataRetriever to get the width and height, I first retrieve a Bitmap from the video file and then setting the orientation according to the width and hight of the Bitmap, as shown below:

    private void rotateScreen() {
        try {
            //Create a new instance of MediaMetadataRetriever
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            //Declare the Bitmap
            Bitmap bmp;
            //Set the video Uri as data source for MediaMetadataRetriever
            retriever.setDataSource(this, mVideoUri);
            //Get one "frame"/bitmap - * NOTE - no time was set, so the first available frame will be used
            bmp = retriever.getFrameAtTime();
    
            //Get the bitmap width and height
            videoWidth = bmp.getWidth();
            videoHeight = bmp.getHeight();
    
            //If the width is bigger then the height then it means that the video was taken in landscape mode and we should set the orientation to landscape
            if (videoWidth > videoHeight) {
                //Set orientation to landscape
                this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            }
            //If the width is smaller then the height then it means that the video was taken in portrait mode and we should set the orientation to portrait
            if (videoWidth < videoHeight) {
                //Set orientation to portrait
                this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
    
        } catch (RuntimeException ex) {
            //error occurred
            Log.e("MediaMetadataRetriever", "- Failed to rotate the video");
    
        }
    }