Как воспроизводить видео в полноэкранном режиме в альбомной ориентации с помощью exoplayer

Я использую exoplayer для воспроизведения видео с URL-адреса в моем приложении для Android. В портретной ориентации все работает как положено (с использованием окна просмотра, фрагментов и вкладок внутри активности). Моя цель - воспроизвести видео в полноэкранном режиме, когда пользователь находится в альбомной ориентации. Это означает, что только видео будет воспроизводиться в альбомной ориентации, а все остальные детали исчезнут и вернутся к исходному макету в портретной ориентации. Как я могу этого добиться? или как лучше всего этого добиться? любой образец кода будет признателен.

Видео для воспроизведения в портретной ориентации


person Jean-Pascal MEWENEMESSE    schedule 12.10.2017    source источник
comment
Привет, если вы нашли решение проблемы, пожалуйста, опубликуйте его и примите его как ответ. Это поможет другим.   -  person Sandeep Yohans    schedule 10.07.2018


Ответы (9)


Я новичок, так что это лучшее, с чем я могу помочь, кстати, я тестировал это в приложении Exoplayer Demo, я изменил высоту exoplayer на 600 пикселей и применил этот код, и он отлично сработал.

добавьте этот код для определения ориентации экрана

  @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);
  }
}

кстати, если вы не используете FrameLayout, а RelativeLayout

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

Я забыл, что вам нужно скрыть строку действия или заголовка, надеюсь, этот код поможет, добавьте эти коды внутри кода выше, также я думаю, вам нужно будет расширить свою активность до AppCompatActivity, чтобы код getSupportActionBar работал.

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

также это может помочь установить весь проект в полноэкранном режиме, чтобы скрыть строку состояния. и т. д., необходимо добавить внутри onConfigurationChanged в зависимости от ориентации экрана.

В LandScape

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

Для выхода из полноэкранного режима в ПОРТРЕТЕ

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

Я отредактировал код и добавил View.SYSTEM_UI_FLAG_IMMERSIVE, чтобы строка состояния не отображалась, когда пользователь нажимает кнопку управления в видео.

person Daiwik Dan    schedule 13.10.2017
comment
Большое спасибо за ответ. Но в конце концов я нашел этот проект github, который решил мою проблему с помощью Dialog github.com/GeoffLedak/ExoplayerFullscreen - person Jean-Pascal MEWENEMESSE; 15.10.2017
comment
Ключом к использованию вашего решения было также установить android:configChanges="orientation|screenSize|keyboardHidden" в манифесте! - person schneida; 15.03.2018
comment
это правда, они уже существуют по умолчанию в проекте exoplayer, поэтому я думаю, что по умолчанию любой, кто импортировал exoplayer в свой проект, также скопирует и вставит настройки из манифеста exoplayer в свой манифест проекта, а также будет импортировать те, которые скрывают панель действий ... и Т. Д. вот что есть в манифесте exoplayer: android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode" - person Daiwik Dan; 16.03.2018
comment
Я думаю, что это очень хорошее решение: оно полностью оставляет управление вращением системе Android, угрожая экземпляру exoplayer как простому представлению. вам не нужно беспокоиться о жизненном цикле экземпляра exoplayer. спасибо, что поделились этим. - person Andrea De Gaetano; 18.09.2018

Вы можете проверить ориентацию при настройке Player и установить соответствующие параметры:

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);
    }

И скройте панель действий:

((AppCompatActivity) getActivity()).getSupportActionBar().hide();
person Lior Michelzon    schedule 10.05.2018
comment
Кажется, это хорошо работает для устройств с аппаратными кнопками, но для устройств с виртуальными кнопками на экране он фактически не раздувается до полноэкранного режима. (кнопки и строка состояния вверху по-прежнему отображаются) - person Mr.Drew; 26.06.2018

Мое решение с привязкой данных:

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);
}

Мой проект здесь

person Nikolay Krasilnikov    schedule 12.05.2018
comment
ссылка на проект отсутствует - person Sandeep Yohans; 12.02.2019

Для экранов с аппаратными кнопками, если никакие другие представления не разделяют экран с PlayerView ExoPlayer, по умолчанию он заполнит весь экран. Однако для устройств с виртуальными кнопками на экране он не будет заполнять весь экран. в моем случае проблемы исправлены путем добавления этой строки в PlayerView.

ads:resize_mode="fill"

поскольку у меня есть реклама admob в макете активности, я добавил эту строку в верхний тег RelativeLayout.

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

Я знаю, что это не имеет смысла, однако использование android:resize_mode="fill" приведет к ошибке построения градиента.

также вы можете удалить системный интерфейс, чтобы получить еще больше места:

    @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);

}

для получения дополнительной информации посетите страницу разработчика Android https://developer.android.com/training/system-ui/immersive

person solidfox    schedule 06.07.2018
comment
android: resize_mode = fill выдает ошибку, потому что это не свойство android. Это свойство пользовательского компонента. Вы можете использовать что угодно, кроме android. - person Raj Suvariya; 08.07.2018

Обязательно установите длину и ширину экрана плеера в соответствии с его родительским видом в альбомном режиме.

  1. Используйте это, чтобы скрыть строку состояния: getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

  2. Используйте это, чтобы скрыть панель навигации: getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

person 6rchid    schedule 13.02.2019

Думаю, здесь мы упускаем более очевидный ответ. Просто создайте новый файл макета в каталоге layout-land, чтобы новый файл макета применялся, когда вы находитесь в альбомном режиме.

В этом новом файле макета просто измените ExoPlayer layout_height на match_parent, чтобы он занимал весь экран.

person Jin    schedule 19.02.2019

Вы можете создать диалог для ландшафтного режима, сначала инициализировать диалог,

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();
        }
    };
}

Теперь, как показано ниже, вы инициализируете свою полноэкранную кнопку: -

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();
            }
        }
    });

тогда вы можете открывать и закрывать полноэкранный режим следующим образом: -

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);
}

Я использую FrameLayout в качестве родителя PlayerView в xml, как показано ниже:

<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>
person Abhishek Kumar    schedule 15.03.2019
comment
объясните это поподробнее, ((FrameLayout) findViewById(R.id.main_media_frame)).addView(playerView); какой формат кадра - person Mahmoud Mabrok; 28.10.2020
comment
спасибо, теперь я не могу использовать это с kotlin public void onBackPressed() { if (mExoPlayerFullscreen) { //mExoPlayerFullscreen is a boolean to check if it is already fullscreen or not closeFullscreenDialog(); } super.onBackPressed(); } - person Mahmoud Mabrok; 28.10.2020
comment
onBackPressed было переопределено. Я не вижу проблем с onBackPressed () - person Abhishek Kumar; 28.10.2020
comment
не могли бы вы добавить колтинную версию кода для создания диалога, пожалуйста - person Mahmoud Mabrok; 28.10.2020
comment
также с wrap_content, поскольку видео с параметрами не подходит для полноэкранного режима, когда я сделал его для соответствия родительскому, и возврат из полноэкранного просмотра остается на весь экран - person Mahmoud Mabrok; 28.10.2020

Самый простой способ установить ориентацию экрана.
Возьмите логическое значение:

boolean abc = false;

В настоящее время:

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;
}

Я использую recyclerview, поэтому я использовал list.add.
Вместо этого вы можете использовать эту строку кода:

imageView.setImageDrawable(getResources().getDrawable(R.drawable.yourIamge));
person Ukasha    schedule 05.01.2021

Я добавил в playerView:

app:resize_mode="fixed_width"

И тогда все работает хорошо

person calincan mircea    schedule 28.05.2018