Merge pull request #2763 from wood1986/feat/expo-fullscreen
feat: add full screen support based on expo-av implementation
This commit is contained in:
commit
c8b54f3bbe
@ -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'
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
post(() -> {
|
||||||
decorView.setSystemUiVisibility(uiOptions);
|
decorView.setSystemUiVisibility(uiOptions);
|
||||||
|
if (controls) {
|
||||||
|
fullScreenPlayerView.show();
|
||||||
|
}
|
||||||
eventEmitter.fullscreenDidPresent();
|
eventEmitter.fullscreenDidPresent();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
|
uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
|
||||||
eventEmitter.fullscreenWillDismiss();
|
eventEmitter.fullscreenWillDismiss();
|
||||||
|
post(() -> {
|
||||||
decorView.setSystemUiVisibility(uiOptions);
|
decorView.setSystemUiVisibility(uiOptions);
|
||||||
|
if (controls) {
|
||||||
|
fullScreenPlayerView.dismiss();
|
||||||
|
reLayout(exoPlayerView);
|
||||||
|
}
|
||||||
eventEmitter.fullscreenDidDismiss();
|
eventEmitter.fullscreenDidDismiss();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
7
android/src/main/res/values/styles.xml
Normal file
7
android/src/main/res/values/styles.xml
Normal 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>
|
Loading…
Reference in New Issue
Block a user