How to play video full screen in landscape using exoplayer
Asked Answered
R

9

19

I am using exoplayer to play video from url in my android app. In portrait everything work as expected (using viewpager, fragments and tabs inside activity). My goal is to play the video in full screen when the user is in landscape. It means only the video will play in landscape and all other details will desapear and return back to the original layout when portrait. How can I achieve this please? or what is the best way to achieve this? any sample code will be appreciate.

Video to be play when portrait

Razzia answered 12/10, 2017 at 15:43 Comment(1)
Hi, if you have found any solution for the problem, kindly post it and accept is as answer. It will help others.Selfappointed
S
12

i am a noob so this is the best i can help with, btw I tested this in the Exoplayer Demo application, i changed the exoplayer height to 600px and i applied this code and it worked perfectly.

add this Code to detect screen orientation

  @Override
  public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);

  // Checking the orientation of the screen
  if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
     //First Hide other objects (listview or recyclerview), better hide them using Gone.
     FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) simpleExoPlayerView.getLayoutParams();
     params.width=params.MATCH_PARENT;
     params.height=params.MATCH_PARENT;
     simpleExoPlayerView.setLayoutParams(params);
  } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
     //unhide your objects here.
     FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) simpleExoPlayerView.getLayoutParams();
     params.width=params.MATCH_PARENT;
     params.height=600;
     simpleExoPlayerView.setLayoutParams(params);
  }
}

btw in case you are not using FrameLayout but RelativeLayout

      RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) simpleExoPlayerView.getLayoutParams();

I forgot that you need to hide the action or title bar, hope this code helps, add these codes inside the code above, also i think you will need to extend your activity to AppCompatActivity for getSupportActionBar code to work.

if(getSupportActionBar()!=null) {
   getSupportActionBar().hide();
}
//To show the action bar
if(getSupportActionBar()!=null) {
   getSupportActionBar().show();
 }

also this may help to set the whole project in full screen, to hide status bar.etc, must be added inside onConfigurationChanged based on screen orientation.

In LandScape

ExoPlayerActivity.this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN || View.SYSTEM_UI_FLAG_IMMERSIVE);

To exit from fullscreen in PORTRAIT

ExoPlayerActivity.this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

I edited the code, I added View.SYSTEM_UI_FLAG_IMMERSIVE to prevent status bar from showing when user click on the control button in the video.

Smithson answered 13/10, 2017 at 19:31 Comment(4)
Thank you very much for your answer. But finaly I found this github project wich resolve my problem by using Dialog github.com/GeoffLedak/ExoplayerFullscreenRazzia
They key to using your solution was to also set android:configChanges="orientation|screenSize|keyboardHidden" in the manifest!Carborundum
that's true, that already exist by default in exoplayer project, so I think by default anyone who imported exoplayer to his project will also copy and past the settings from exoplayer manifest to his project manifest and will also import the them that hides action bar..etc. here is what exoplayer manifest has: android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"Smithson
I think this is a very good solution: it completely leave the "handling" of rotation to the android system threating the exoplayer instance as a "simple" view. you don't have to worry about lifecycle of the exoplayer instance. thanks you for sharing it.Lennox
I
2

You can check the orientation while setting the Player and set the params accordingly:

if (getActivity().getResources().getConfiguration().orientation == 
Configuration.ORIENTATION_LANDSCAPE) {
        params = (LinearLayout.LayoutParams) 
exoPlayerView.getLayoutParams();
        params.width = params.MATCH_PARENT;
        params.height = params.MATCH_PARENT;
        exoPlayerView.setLayoutParams(params);
    }

And hide the action bar :

((AppCompatActivity) getActivity()).getSupportActionBar().hide();
Inainability answered 10/5, 2018 at 9:35 Comment(1)
This seems to work well for devices with hardware buttons, but for devices with virtual buttons on the screen, it doesn't actually inflate to full screen. (buttons and status bar at top are still shown)Marabelle
M
2

My solution with data binding:

layout.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>
    <import type="android.view.View" />
    <variable
        name="orientationLandscape"
        type="boolean" />

    <variable
        name="step"
        type="com.udacity.zeban.baking.data.models.Step" />
</data>

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.exoplayer2.ui.SimpleExoPlayerView
        android:id="@+id/step_video"
        android:layout_width="match_parent"
        android:layout_height="@dimen/player_height"
        app:layout_constraintBottom_toTopOf="@+id/scroll"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_height="@{orientationLandscape}" />

    <ScrollView
        android:id="@+id/scroll"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/step_video">

        <android.support.v7.widget.CardView
            android:id="@+id/description"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/spacing_small"
            android:visibility="@{orientationLandscape ? View.GONE : View.VISIBLE}">

            <TextView
                android:id="@+id/step_description"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/spacing_small"
                android:text="@{step.getDescription()}"
                tools:text="@tools:sample/lorem/random" />

        </android.support.v7.widget.CardView>
    </ScrollView>
</android.support.constraint.ConstraintLayout>

and add this in your actvity or fragment:

@BindingAdapter("layout_height")
public static void setLayoutHeight(View view, boolean orientationLandscape) {
    view.getLayoutParams().height = orientationLandscape ? RelativeLayout.LayoutParams.MATCH_PARENT : 600;
}

@Override
public void onResume() {
    super.onResume();
    binding.setOrientationLandscape(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
}

My project here

Merchantable answered 12/5, 2018 at 16:27 Comment(1)
link to project is missingSelfappointed
A
2

You can make a dialog for the landscape mode, first initialize a dialog,

private void initFullscreenDialog() {
    mFullScreenDialog = new Dialog(mContext, android.R.style.Theme_Black_NoTitleBar_Fullscreen) {
        public void onBackPressed() {
            if (mExoPlayerFullscreen) {    //mExoPlayerFullscreen is a boolean to check if it is already fullscreen or not
                closeFullscreenDialog();
            }
            super.onBackPressed();
        }
    };
}

Now as below you'll initialize your fullscreen button:-

mFullScreenButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!mExoPlayerFullscreen) {
                ((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
                openFullscreenDialog();
            } else {
                ((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
                closeFullscreenDialog();
            }
        }
    });

then you can open and close fullscreen as follows :-

private void openFullscreenDialog() {
    ((ViewGroup) playerView.getParent()).removeView(playerView);
    mFullScreenDialog.addContentView(playerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    mFullScreenIcon.setImageResource(R.drawable.ic_exit_fullscreen);
    mExoPlayerFullscreen = true;
    mFullScreenDialog.show();
}

private void closeFullscreenDialog() {
    ((ViewGroup) playerView.getParent()).removeView(playerView);
    ((FrameLayout) findViewById(R.id.main_media_frame)).addView(playerView);
    mExoPlayerFullscreen = false;
    mFullScreenDialog.dismiss();
    mFullScreenIcon.setImageResource(R.drawable.ic_fullscreen);
}

I'm using FrameLayout as parent of PlayerView in xml as below :

<FrameLayout
        android:id="@+id/main_media_frame2"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_below="@+id/common_item_header_container"
        android:background="#000000">

        <com.google.android.exoplayer2.ui.PlayerView
            android:id="@+id/player_view"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:focusable="true"></com.google.android.exoplayer2.ui.PlayerView>
    </FrameLayout>
Absolutely answered 15/3, 2019 at 4:33 Comment(5)
explain this more please, ((FrameLayout) findViewById(R.id.main_media_frame)).addView(playerView); which framelayoutAsbury
thanks, now i can not use this with kotlin public void onBackPressed() { if (mExoPlayerFullscreen) { //mExoPlayerFullscreen is a boolean to check if it is already fullscreen or not closeFullscreenDialog(); } super.onBackPressed(); }Asbury
onBackPressed has be overridden. I don't there should be any problem with onBackPressed()Absolutely
could u add koltin version of code for making dialoge, pleaseAsbury
also with wrap_content as params video is not fit full screen, when i made it to match parent , and return from full screen view remain take full screenAsbury
B
1

For screens with hardware buttons, If no other views share the screen with PlayerView of ExoPlayer, it will fill the entire screen by default. However for devices with virtual buttons on the screen, it will not fill the entire screen. in my case the issues fixed by adding this line to PlayerView.

ads:resize_mode="fill"

as I have admob ads in the activity layout, I have added this line in the top RelativeLayout tag.

xmlns:ads="http://schemas.android.com/apk/res-auto"

I know it doesn't make sense, however using android:resize_mode="fill" will gave you gradle building error.

also you might remove system UI for even more space:

    @Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        hideSystemUI();
    }
}

private void hideSystemUI() {
    // Enables  "lean back" mode
    // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
    View decorView = getWindow().getDecorView();
    decorView.setSystemUiVisibility(
            // Hide the nav bar and status bar
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN);

}

for more information please visit android developer page https://developer.android.com/training/system-ui/immersive

Brewage answered 6/7, 2018 at 21:49 Comment(2)
android:resize_mode="fill" gives you an error because it's not an android property. It's the custom component's property. You can use anything except android.Stere
i used app:resize_mode="fill" but in portrait its showing starched portrait screen. Working fine for landscape mode but not portrait mode, any ideaSchiff
N
1

Be sure to set the length and width of the player view to match with its parent, in landscape mode.

  1. Use this to hide the status bar: getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

  2. Use this to hide the navigation bar: getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

Nich answered 13/2, 2019 at 4:41 Comment(0)
R
0

I think we are missing the more obvious answer here. Just create a new layout file in layout-land directory so that the new layout file will be applied when you are in landscape mode.

In this new layout file, simply change your ExoPlayer's layout_height to be match_parent so that it takes up the whole screen.

Redwing answered 19/2, 2019 at 6:15 Comment(1)
how we can use another xml for landscape ?Schiff
H
0

The simplest way of setting screen orientation.
Take a boolean value:

boolean abc = false;

Now:

if (abc) {
    list.set(position, new IconsModel(R.drawable.screenlocked, "Portrait"));
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    abc = false;
} else {
    list.set(position, new IconsModel(R.drawable.screenrotate, "Landscape"));
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    abc = true;
}

I am using recyclerview thats why I have used list.add.
You can use this line of code instead:

imageView.setImageDrawable(getResources().getDrawable(R.drawable.yourIamge));
Hyperplane answered 5/1, 2021 at 10:47 Comment(0)
E
-8

I added to playerView:

app:resize_mode="fixed_width"

And then all works good

Enfleurage answered 28/5, 2018 at 10:8 Comment(1)
Its working but it hides or cuts bottom screen , any solution ? i used app:resize_mode="fill" but in portrait its showing starched portrait screen.Schiff

© 2022 - 2024 — McMap. All rights reserved.