diff --git a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java index ebe05d16..db56f656 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java @@ -108,6 +108,10 @@ public final class ExoPlayerView extends FrameLayout implements AdViewProvider { } } + public boolean isPlaying() { + return player != null && player.isPlaying(); + } + public void setSubtitleStyle(SubtitleStyle style) { // ensure we reset subtile style before reapplying it subtitleLayout.setUserDefaultStyle(); diff --git a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java index f207ce8f..b5d170a0 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.java @@ -3,28 +3,73 @@ package com.brentvatne.exoplayer; import android.annotation.SuppressLint; import android.app.Dialog; import android.content.Context; +import android.os.Handler; import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ImageButton; import androidx.activity.OnBackPressedCallback; import androidx.media3.ui.LegacyPlayerControlView; +import com.brentvatne.common.toolbox.DebugLog; + +import java.lang.ref.WeakReference; + @SuppressLint("PrivateResource") public class FullScreenPlayerView extends Dialog { private final LegacyPlayerControlView playerControlView; private final ExoPlayerView exoPlayerView; + private final ReactExoplayerView reactExoplayerView; private ViewGroup parent; private final FrameLayout containerView; private final OnBackPressedCallback onBackPressedCallback; + private final Handler mKeepScreenOnHandler; + private final Runnable mKeepScreenOnUpdater; - public FullScreenPlayerView(Context context, ExoPlayerView exoPlayerView, LegacyPlayerControlView playerControlView, OnBackPressedCallback onBackPressedCallback) { + private static class KeepScreenOnUpdater implements Runnable { + private final static long UPDATE_KEEP_SCREEN_ON_FLAG_MS = 200; + private final WeakReference mFullscreenPlayer; + + KeepScreenOnUpdater(FullScreenPlayerView player) { + mFullscreenPlayer = new WeakReference<>(player); + } + + @Override + public void run() { + try { + FullScreenPlayerView fullscreenVideoPlayer = mFullscreenPlayer.get(); + if (fullscreenVideoPlayer != null) { + final Window window = fullscreenVideoPlayer.getWindow(); + if (window != null) { + boolean isPlaying = fullscreenVideoPlayer.exoPlayerView.isPlaying(); + if (isPlaying) { + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } else { + window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + fullscreenVideoPlayer.mKeepScreenOnHandler.postDelayed(this, UPDATE_KEEP_SCREEN_ON_FLAG_MS); + } + } catch (Exception ex) { + DebugLog.e("ExoPlayer Exception", "Failed to flag FLAG_KEEP_SCREEN_ON on fullscreeen."); + DebugLog.e("ExoPlayer Exception", ex.toString()); + } + } + } + + public FullScreenPlayerView(Context context, ExoPlayerView exoPlayerView, ReactExoplayerView reactExoplayerView, LegacyPlayerControlView playerControlView, OnBackPressedCallback onBackPressedCallback) { super(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen); this.playerControlView = playerControlView; this.exoPlayerView = exoPlayerView; + this.reactExoplayerView = reactExoplayerView; this.onBackPressedCallback = onBackPressedCallback; containerView = new FrameLayout(context); setContentView(containerView, generateDefaultLayoutParams()); + + mKeepScreenOnUpdater = new KeepScreenOnUpdater(this); + mKeepScreenOnHandler = new Handler(); } @Override @@ -53,6 +98,7 @@ public class FullScreenPlayerView extends Dialog { @Override protected void onStop() { + mKeepScreenOnHandler.removeCallbacks(mKeepScreenOnUpdater); containerView.removeView(exoPlayerView); parent.addView(exoPlayerView, generateDefaultLayoutParams()); @@ -70,6 +116,15 @@ public class FullScreenPlayerView extends Dialog { super.onStop(); } + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + + if (reactExoplayerView.getPreventsDisplaySleepDuringVideoPlayback()) { + mKeepScreenOnHandler.post(mKeepScreenOnUpdater); + } + } + private FrameLayout.LayoutParams generateDefaultLayoutParams() { FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 4343698e..c13118aa 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -406,7 +406,7 @@ public class ReactExoplayerView extends FrameLayout implements } if (fullScreenPlayerView == null) { - fullScreenPlayerView = new FullScreenPlayerView(getContext(), exoPlayerView, playerControlView, new OnBackPressedCallback(true) { + fullScreenPlayerView = new FullScreenPlayerView(getContext(), exoPlayerView, this, playerControlView, new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { setFullscreen(false); @@ -1966,6 +1966,10 @@ public class ReactExoplayerView extends FrameLayout implements this.disableBuffering = disableBuffering; } + public boolean getPreventsDisplaySleepDuringVideoPlayback() { + return preventsDisplaySleepDuringVideoPlayback; + } + private void updateFullScreenButtonVisbility() { if (playerControlView != null) { final ImageButton fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen); diff --git a/examples/basic/src/VideoPlayer.tsx b/examples/basic/src/VideoPlayer.tsx index a92d71bc..2f69b21b 100644 --- a/examples/basic/src/VideoPlayer.tsx +++ b/examples/basic/src/VideoPlayer.tsx @@ -790,6 +790,7 @@ class VideoPlayer extends Component { selectedTextTrack={this.state.selectedTextTrack} selectedAudioTrack={this.state.selectedAudioTrack} playInBackground={false} + preventsDisplaySleepDuringVideoPlayback={true} /> );