Merge pull request #2763 from wood1986/feat/expo-fullscreen

feat: add full screen support based on expo-av implementation
This commit is contained in:
Olivier Bouillet 2022-09-11 11:55:36 +02:00 committed by GitHub
commit c8b54f3bbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 136 additions and 6 deletions

View File

@ -41,6 +41,7 @@ dependencies {
implementation "androidx.annotation:annotation:1.1.0" implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.core:core:1.1.0" implementation "androidx.core:core:1.1.0"
implementation "androidx.media:media: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.18.1') { implementation('com.google.android.exoplayer:extension-okhttp:2.18.1') {
exclude group: 'com.squareup.okhttp3', module: 'okhttp' exclude group: 'com.squareup.okhttp3', module: 'okhttp'

View File

@ -0,0 +1,80 @@
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 androidx.activity.OnBackPressedCallback;
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;
private final OnBackPressedCallback onBackPressedCallback;
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());
parent.removeView(exoPlayerView);
containerView.addView(exoPlayerView, generateDefaultLayoutParams());
if (playerControlView != null) {
ImageButton imageButton = playerControlView.findViewById(com.brentvatne.react.R.id.exo_fullscreen);
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());
}
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.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());
}
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;
}
}

View File

@ -17,6 +17,8 @@ import android.view.accessibility.CaptioningManager;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import androidx.activity.OnBackPressedCallback;
import com.brentvatne.react.R; import com.brentvatne.react.R;
import com.brentvatne.receiver.AudioBecomingNoisyReceiver; import com.brentvatne.receiver.AudioBecomingNoisyReceiver;
import com.brentvatne.receiver.BecomingNoisyListener; import com.brentvatne.receiver.BecomingNoisyListener;
@ -141,6 +143,7 @@ class ReactExoplayerView extends FrameLayout implements
private Player.Listener eventListener; private Player.Listener eventListener;
private ExoPlayerView exoPlayerView; private ExoPlayerView exoPlayerView;
private FullScreenPlayerView fullScreenPlayerView;
private DataSource.Factory mediaDataSourceFactory; private DataSource.Factory mediaDataSourceFactory;
private ExoPlayer player; private ExoPlayer player;
@ -368,7 +371,6 @@ class ReactExoplayerView extends FrameLayout implements
// Setting the player for the playerControlView // Setting the player for the playerControlView
playerControlView.setPlayer(player); playerControlView.setPlayer(player);
playerControlView.show();
playPauseControlContainer = playerControlView.findViewById(R.id.exo_play_pause_container); playPauseControlContainer = playerControlView.findViewById(R.id.exo_play_pause_container);
// Invoking onClick event for exoplayerView // Invoking onClick event for exoplayerView
@ -400,6 +402,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 // Invoking onPlaybackStateChanged and onPlayWhenReadyChanged events for Player
eventListener = new Player.Listener() { eventListener = new Player.Listener() {
@Override @Override
@ -442,6 +448,7 @@ class ReactExoplayerView extends FrameLayout implements
removeViewAt(indexOfPC); removeViewAt(indexOfPC);
} }
addView(playerControlView, 1, layoutParams); addView(playerControlView, 1, layoutParams);
reLayout(playerControlView);
} }
/** /**
@ -589,7 +596,7 @@ class ReactExoplayerView extends FrameLayout implements
new DefaultRenderersFactory(getContext()) new DefaultRenderersFactory(getContext())
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF); .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
player = new ExoPlayer.Builder(getContext(), renderersFactory) player = new ExoPlayer.Builder(getContext(), renderersFactory)
.setTrackSelector(self.trackSelector) .setTrackSelector(self.trackSelector)
.setBandwidthMeter(bandwidthMeter) .setBandwidthMeter(bandwidthMeter)
.setLoadControl(loadControl) .setLoadControl(loadControl)
.build(); .build();
@ -665,6 +672,12 @@ class ReactExoplayerView extends FrameLayout implements
setControls(controls); setControls(controls);
applyModifiers(); applyModifiers();
startBufferCheckTimer(); startBufferCheckTimer();
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 { private DrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl, String[] keyRequestPropertiesArray) throws UnsupportedDrmException {
@ -1760,6 +1773,16 @@ class ReactExoplayerView extends FrameLayout implements
if (activity == null) { if (activity == null) {
return; return;
} }
if (fullScreenPlayerView == null) {
fullScreenPlayerView = new FullScreenPlayerView(getContext(), exoPlayerView, playerControlView, new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
setFullscreen(false);
}
});
}
Window window = activity.getWindow(); Window window = activity.getWindow();
View decorView = window.getDecorView(); View decorView = window.getDecorView();
int uiOptions; int uiOptions;
@ -1773,13 +1796,24 @@ class ReactExoplayerView extends FrameLayout implements
| SYSTEM_UI_FLAG_FULLSCREEN; | SYSTEM_UI_FLAG_FULLSCREEN;
} }
eventEmitter.fullscreenWillPresent(); eventEmitter.fullscreenWillPresent();
decorView.setSystemUiVisibility(uiOptions); post(() -> {
eventEmitter.fullscreenDidPresent(); decorView.setSystemUiVisibility(uiOptions);
if (controls) {
fullScreenPlayerView.show();
}
eventEmitter.fullscreenDidPresent();
});
} else { } else {
uiOptions = View.SYSTEM_UI_FLAG_VISIBLE; uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
eventEmitter.fullscreenWillDismiss(); eventEmitter.fullscreenWillDismiss();
decorView.setSystemUiVisibility(uiOptions); post(() -> {
eventEmitter.fullscreenDidDismiss(); decorView.setSystemUiVisibility(uiOptions);
if (controls) {
fullScreenPlayerView.dismiss();
reLayout(exoPlayerView);
}
eventEmitter.fullscreenDidDismiss();
});
} }
} }

View File

@ -71,6 +71,14 @@
android:paddingRight="4dp" android:paddingRight="4dp"
android:includeFontPadding="false" android:includeFontPadding="false"
android:textColor="#FFBEBEBE"/> android:textColor="#FFBEBEBE"/>
<ImageButton
android:id="@id/exo_fullscreen"
style="@style/ExoMediaButton.FullScreen"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="4dp"
android:scaleType="fitCenter" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ExoMediaButton.FullScreen">
<item name="android:src">@drawable/exo_icon_fullscreen_enter</item>
<item name="android:contentDescription">@string/exo_controls_fullscreen_enter_description</item>
</style>
</resources>