From b144a50f41bdc6ea389767f8c4d0076d773aee70 Mon Sep 17 00:00:00 2001 From: wood1986 <5212215+wood1986@users.noreply.github.com> Date: Thu, 14 Jul 2022 11:10:18 -0700 Subject: [PATCH 1/9] feat: add full screen support based on expo-av implementation --- .../exoplayer/FullScreenPlayerView.java | 71 +++++++++++++++++++ .../exoplayer/ReactExoplayerView.java | 11 ++- .../res/layout/exo_player_control_view.xml | 8 +++ android/src/main/res/values/styles.xml | 7 ++ 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java create mode 100644 android/src/main/res/values/styles.xml diff --git a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java new file mode 100644 index 00000000..72e09aae --- /dev/null +++ b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java @@ -0,0 +1,71 @@ +package com.brentvatne.exoplayer; + +import android.app.Dialog; +import android.content.Context; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageButton; + +import com.google.android.exoplayer2.ui.PlayerControlView; + +public class FullScreenPlayerView extends Dialog { + private final PlayerControlView playerControlView; + private final ExoPlayerView exoPlayerView; + private ViewGroup parent; + private final FrameLayout containerView; + + public FullScreenPlayerView(Context context, ExoPlayerView exoPlayerView, PlayerControlView playerControlView) { + super(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen); + this.playerControlView = playerControlView; + this.exoPlayerView = exoPlayerView; + containerView = new FrameLayout(context); + setContentView(containerView, generateDefaultLayoutParams()); + } + + @Override + protected void onStart() { + parent = (FrameLayout)(exoPlayerView.getParent()); + + parent.removeView(exoPlayerView); + containerView.addView(exoPlayerView, generateDefaultLayoutParams()); + + if (playerControlView != null) { + ImageButton imageButton = playerControlView.findViewById(com.brentvatne.react.R.id.exo_fullscreen); + imageButton.setBackgroundResource(com.google.android.exoplayer2.ui.R.drawable.exo_icon_fullscreen_exit); + imageButton.setContentDescription(getContext().getString(com.google.android.exoplayer2.ui.R.string.exo_controls_fullscreen_exit_description)); + parent.removeView(playerControlView); + containerView.addView(playerControlView, generateDefaultLayoutParams()); + + } + + super.onStart(); + } + + @Override + protected void onStop() { + containerView.removeView(exoPlayerView); + parent.addView(exoPlayerView, generateDefaultLayoutParams()); + + if (playerControlView != null) { + ImageButton imageButton = playerControlView.findViewById(com.brentvatne.react.R.id.exo_fullscreen); + imageButton.setBackgroundResource(com.google.android.exoplayer2.ui.R.drawable.exo_icon_fullscreen_enter); + imageButton.setContentDescription(getContext().getString(com.google.android.exoplayer2.ui.R.string.exo_controls_fullscreen_enter_description)); + containerView.removeView(playerControlView); + parent.addView(playerControlView, generateDefaultLayoutParams()); + } + + parent.requestLayout(); + parent = null; + + super.onStop(); + } + + private FrameLayout.LayoutParams generateDefaultLayoutParams() { + FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.MATCH_PARENT + ); + layoutParams.setMargins(0, 0, 0, 0); + return layoutParams; + } +} diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 9a334132..c80d86f5 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -140,6 +140,7 @@ class ReactExoplayerView extends FrameLayout implements private Player.Listener eventListener; private ExoPlayerView exoPlayerView; + private FullScreenPlayerView fullScreenPlayerView; private DataSource.Factory mediaDataSourceFactory; private ExoPlayer player; @@ -399,6 +400,10 @@ class ReactExoplayerView extends FrameLayout implements } }); + //Handling the fullScreenButton click event + ImageButton fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen); + fullScreenButton.setOnClickListener(v -> setFullscreen(!isFullscreen)); + // Invoking onPlaybackStateChanged and onPlayWhenReadyChanged events for Player eventListener = new Player.Listener() { @Override @@ -664,6 +669,7 @@ class ReactExoplayerView extends FrameLayout implements setControls(controls); applyModifiers(); startBufferCheckTimer(); + fullScreenPlayerView = new FullScreenPlayerView(getContext(), exoPlayerView, playerControlView); } private DrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl, String[] keyRequestPropertiesArray) throws UnsupportedDrmException { @@ -1770,14 +1776,15 @@ class ReactExoplayerView extends FrameLayout implements | SYSTEM_UI_FLAG_FULLSCREEN; } eventEmitter.fullscreenWillPresent(); - decorView.setSystemUiVisibility(uiOptions); + fullScreenPlayerView.show(); eventEmitter.fullscreenDidPresent(); } else { uiOptions = View.SYSTEM_UI_FLAG_VISIBLE; eventEmitter.fullscreenWillDismiss(); - decorView.setSystemUiVisibility(uiOptions); + fullScreenPlayerView.dismiss(); eventEmitter.fullscreenDidDismiss(); } + post(() -> decorView.setSystemUiVisibility(uiOptions)); } public void setUseTextureView(boolean useTextureView) { diff --git a/android/src/main/res/layout/exo_player_control_view.xml b/android/src/main/res/layout/exo_player_control_view.xml index becee6a9..19440912 100644 --- a/android/src/main/res/layout/exo_player_control_view.xml +++ b/android/src/main/res/layout/exo_player_control_view.xml @@ -71,6 +71,14 @@ android:paddingRight="4dp" android:includeFontPadding="false" android:textColor="#FFBEBEBE"/> + + diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml new file mode 100644 index 00000000..3459d9d6 --- /dev/null +++ b/android/src/main/res/values/styles.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file From 470ca7bf60256b8cf97d0d3db9d91eaf2e034e3d Mon Sep 17 00:00:00 2001 From: wood1986 <5212215+wood1986@users.noreply.github.com> Date: Thu, 14 Jul 2022 15:50:25 -0700 Subject: [PATCH 2/9] WIP --- .../java/com/brentvatne/exoplayer/FullScreenPlayerView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java index 72e09aae..5633829c 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java @@ -31,7 +31,7 @@ public class FullScreenPlayerView extends Dialog { if (playerControlView != null) { ImageButton imageButton = playerControlView.findViewById(com.brentvatne.react.R.id.exo_fullscreen); - imageButton.setBackgroundResource(com.google.android.exoplayer2.ui.R.drawable.exo_icon_fullscreen_exit); + imageButton.setImageResource(com.google.android.exoplayer2.ui.R.drawable.exo_icon_fullscreen_exit); imageButton.setContentDescription(getContext().getString(com.google.android.exoplayer2.ui.R.string.exo_controls_fullscreen_exit_description)); parent.removeView(playerControlView); containerView.addView(playerControlView, generateDefaultLayoutParams()); @@ -48,7 +48,7 @@ public class FullScreenPlayerView extends Dialog { if (playerControlView != null) { ImageButton imageButton = playerControlView.findViewById(com.brentvatne.react.R.id.exo_fullscreen); - imageButton.setBackgroundResource(com.google.android.exoplayer2.ui.R.drawable.exo_icon_fullscreen_enter); + imageButton.setImageResource(com.google.android.exoplayer2.ui.R.drawable.exo_icon_fullscreen_enter); imageButton.setContentDescription(getContext().getString(com.google.android.exoplayer2.ui.R.string.exo_controls_fullscreen_enter_description)); containerView.removeView(playerControlView); parent.addView(playerControlView, generateDefaultLayoutParams()); From 810c62407f4356ed724f3016ccb5f4418eb616f3 Mon Sep 17 00:00:00 2001 From: wood1986 <5212215+wood1986@users.noreply.github.com> Date: Thu, 11 Aug 2022 19:07:10 -0700 Subject: [PATCH 3/9] WIP --- .../main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java | 1 - 1 file changed, 1 deletion(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java index 5633829c..4a7edb1d 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java @@ -35,7 +35,6 @@ public class FullScreenPlayerView extends Dialog { imageButton.setContentDescription(getContext().getString(com.google.android.exoplayer2.ui.R.string.exo_controls_fullscreen_exit_description)); parent.removeView(playerControlView); containerView.addView(playerControlView, generateDefaultLayoutParams()); - } super.onStart(); From 622f9d3f3f2d5bb2bb5568eee740f2972685f255 Mon Sep 17 00:00:00 2001 From: wood1986 <5212215+wood1986@users.noreply.github.com> Date: Thu, 18 Aug 2022 01:12:08 -0700 Subject: [PATCH 4/9] fix: fix the hardware back button --- .../brentvatne/exoplayer/FullScreenPlayerView.java | 12 +++++++++++- .../com/brentvatne/exoplayer/ReactExoplayerView.java | 9 ++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java index 4a7edb1d..f57bb964 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java @@ -6,6 +6,8 @@ import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageButton; +import androidx.activity.OnBackPressedCallback; + import com.google.android.exoplayer2.ui.PlayerControlView; public class FullScreenPlayerView extends Dialog { @@ -13,15 +15,23 @@ public class FullScreenPlayerView extends Dialog { private final ExoPlayerView exoPlayerView; private ViewGroup parent; private final FrameLayout containerView; + private final OnBackPressedCallback onBackPressedCallback; - public FullScreenPlayerView(Context context, ExoPlayerView exoPlayerView, PlayerControlView playerControlView) { + public FullScreenPlayerView(Context context, ExoPlayerView exoPlayerView, PlayerControlView playerControlView, OnBackPressedCallback onBackPressedCallback) { super(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen); this.playerControlView = playerControlView; this.exoPlayerView = exoPlayerView; + this.onBackPressedCallback = onBackPressedCallback; containerView = new FrameLayout(context); setContentView(containerView, generateDefaultLayoutParams()); } + @Override + public void onBackPressed() { + super.onBackPressed(); + onBackPressedCallback.handleOnBackPressed(); + } + @Override protected void onStart() { parent = (FrameLayout)(exoPlayerView.getParent()); diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index c80d86f5..511437da 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -17,6 +17,8 @@ import android.view.accessibility.CaptioningManager; import android.widget.FrameLayout; import android.widget.ImageButton; +import androidx.activity.OnBackPressedCallback; + import com.brentvatne.react.R; import com.brentvatne.receiver.AudioBecomingNoisyReceiver; import com.brentvatne.receiver.BecomingNoisyListener; @@ -669,7 +671,12 @@ class ReactExoplayerView extends FrameLayout implements setControls(controls); applyModifiers(); startBufferCheckTimer(); - fullScreenPlayerView = new FullScreenPlayerView(getContext(), exoPlayerView, playerControlView); + fullScreenPlayerView = new FullScreenPlayerView(getContext(), exoPlayerView, playerControlView, new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + setFullscreen(false); + } + }); } private DrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl, String[] keyRequestPropertiesArray) throws UnsupportedDrmException { From a79c30eaba277db4cd13b3515567c17b7a09ee58 Mon Sep 17 00:00:00 2001 From: wood1986 <5212215+wood1986@users.noreply.github.com> Date: Tue, 23 Aug 2022 13:11:10 -0700 Subject: [PATCH 5/9] fix: fix control not showing up at very first touch --- .../java/com/brentvatne/exoplayer/ReactExoplayerView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 511437da..d1a7d80c 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -370,7 +370,6 @@ class ReactExoplayerView extends FrameLayout implements // Setting the player for the playerControlView playerControlView.setPlayer(player); - playerControlView.show(); playPauseControlContainer = playerControlView.findViewById(R.id.exo_play_pause_container); // Invoking onClick event for exoplayerView @@ -448,6 +447,7 @@ class ReactExoplayerView extends FrameLayout implements removeViewAt(indexOfPC); } addView(playerControlView, 1, layoutParams); + reLayout(playerControlView); } /** @@ -595,7 +595,7 @@ class ReactExoplayerView extends FrameLayout implements new DefaultRenderersFactory(getContext()) .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF); player = new ExoPlayer.Builder(getContext(), renderersFactory) - .setTrackSelector​(self.trackSelector) + .setTrackSelector(self.trackSelector) .setBandwidthMeter(bandwidthMeter) .setLoadControl(loadControl) .build(); From 40e8d9474fc20cc2aedd54ebac07c81b92b76f45 Mon Sep 17 00:00:00 2001 From: wood1986 <5212215+wood1986@users.noreply.github.com> Date: Wed, 7 Sep 2022 14:45:55 -0700 Subject: [PATCH 6/9] fix: add the missing dependency --- android/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/android/build.gradle b/android/build.gradle index a93e7599..90bccb8c 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -41,6 +41,7 @@ dependencies { implementation "androidx.annotation:annotation:1.1.0" implementation "androidx.core:core:1.1.0" implementation "androidx.media:media:1.1.0" + implementation 'androidx.activity:activity:1.4.0' implementation('com.google.android.exoplayer:extension-okhttp:2.17.1') { exclude group: 'com.squareup.okhttp3', module: 'okhttp' From 5203fa63d49c6c503b4e4dac4a97ec1241b75ea2 Mon Sep 17 00:00:00 2001 From: wood1986 <5212215+wood1986@users.noreply.github.com> Date: Thu, 8 Sep 2022 00:31:47 -0700 Subject: [PATCH 7/9] fix: handle the initial fullscreen props --- .../com/brentvatne/exoplayer/ReactExoplayerView.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index d1a7d80c..297a230f 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -1770,6 +1770,16 @@ class ReactExoplayerView extends FrameLayout implements if (activity == null) { return; } + + if (fullScreenPlayerView == null) { + fullScreenPlayerView = new FullScreenPlayerView(getContext(), exoPlayerView, playerControlView, new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + setFullscreen(false); + } + }); + } + Window window = activity.getWindow(); View decorView = window.getDecorView(); int uiOptions; From f0c40f939200a1099c58ece3ec8c3dca63e41173 Mon Sep 17 00:00:00 2001 From: wood1986 <5212215+wood1986@users.noreply.github.com> Date: Sat, 10 Sep 2022 11:52:46 -0700 Subject: [PATCH 8/9] fix: fix the default behaviour --- .../exoplayer/ReactExoplayerView.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 3afe48f3..7e087bb8 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -1796,15 +1796,24 @@ class ReactExoplayerView extends FrameLayout implements | SYSTEM_UI_FLAG_FULLSCREEN; } eventEmitter.fullscreenWillPresent(); - fullScreenPlayerView.show(); - eventEmitter.fullscreenDidPresent(); + post(() -> { + decorView.setSystemUiVisibility(uiOptions); + if (controls) { + fullScreenPlayerView.show(); + } + eventEmitter.fullscreenDidPresent(); + }); } else { uiOptions = View.SYSTEM_UI_FLAG_VISIBLE; eventEmitter.fullscreenWillDismiss(); - fullScreenPlayerView.dismiss(); - eventEmitter.fullscreenDidDismiss(); + post(() -> { + decorView.setSystemUiVisibility(uiOptions); + if (controls) { + fullScreenPlayerView.dismiss(); + } + eventEmitter.fullscreenDidDismiss(); + }); } - post(() -> decorView.setSystemUiVisibility(uiOptions)); } public void setUseTextureView(boolean useTextureView) { From 5b2a4741dd124009c9a3c136943698b966539b8d Mon Sep 17 00:00:00 2001 From: wood1986 <5212215+wood1986@users.noreply.github.com> Date: Sat, 10 Sep 2022 15:08:15 -0700 Subject: [PATCH 9/9] fix: add relayout when fullscreenview dismiss --- .../main/java/com/brentvatne/exoplayer/ReactExoplayerView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 7e087bb8..3e785806 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -1810,6 +1810,7 @@ class ReactExoplayerView extends FrameLayout implements decorView.setSystemUiVisibility(uiOptions); if (controls) { fullScreenPlayerView.dismiss(); + reLayout(exoPlayerView); } eventEmitter.fullscreenDidDismiss(); });