From aa4e1812e9f34c692cbe4f537f5e2827f3dbb195 Mon Sep 17 00:00:00 2001 From: Hampton Maxwell Date: Tue, 17 Jul 2018 17:45:19 -0700 Subject: [PATCH 1/2] Document fullscreen methods & events --- README.md | 75 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index cac87ad2ee..e08e273d1c 100644 --- a/README.md +++ b/README.md @@ -191,21 +191,8 @@ using System.Collections.Generic; onBuffer={this.onBuffer} // Callback when remote video is buffering onEnd={this.onEnd} // Callback when playback finishes onError={this.videoError} // Callback when video cannot be loaded - onFullscreenPlayerWillPresent={this.fullScreenPlayerWillPresent} // Callback before fullscreen starts - onFullscreenPlayerDidPresent={this.fullScreenPlayerDidPresent} // Callback after fullscreen started - onFullscreenPlayerWillDismiss={this.fullScreenPlayerWillDismiss} // Callback before fullscreen stops - onFullscreenPlayerDidDismiss={this.fullScreenPlayerDidDismiss} // Callback after fullscreen stopped style={styles.backgroundVideo} /> -// Later to trigger fullscreen -this.player.presentFullscreenPlayer() - -// Disable fullscreen -this.player.dismissFullscreenPlayer() - -// To set video position in seconds (seek) -this.player.seek(0) - // Later on in your styles.. var styles = StyleSheet.create({ backgroundVideo: { @@ -240,12 +227,18 @@ var styles = StyleSheet.create({ ### Event props * [onAudioBecomingNoisy](#onaudiobecomingnoisy) +* [onFullscreenPlayerWillPresent](#onfullscreenplayerwillpresent) +* [onFullscreenPlayerDidPresent](#onfullscreenplayerdidpresent) +* [onFullscreenPlayerWillDismiss](#onfullscreenplayerwilldismiss) +* [onFullscreenPlayerDidDismiss](#onfullscreenplayerdiddismiss) * [onLoad](#onload) * [onLoadStart](#onloadstart) * [onProgress](#onprogress) * [onTimedMetadata](#ontimedmetadata) ### Methods +* [dismissFullscreenPlayer](#dismissfullscreenplayer) +* [presentFullscreenPlayer](#presentfullscreenplayer) * [seek](#seek) ### Configurable props @@ -460,6 +453,34 @@ Payload: none Platforms: Android ExoPlayer, iOS +#### onFullscreenPlayerWillPresent +Callback function that is called when the player is about to enter fullscreen mode. + +Payload: none + +Platforms: Android ExoPlayer, Android MediaPlayer, iOS + +#### onFullscreenPlayerDidPresent +Callback function that is called when the player has entered fullscreen mode. + +Payload: none + +Platforms: Android ExoPlayer, Android MediaPlayer, iOS + +#### onFullscreenPlayerWillDismiss +Callback function that is called when the player is about to exit fullscreen mode. + +Payload: none + +Platforms: Android ExoPlayer, Android MediaPlayer, iOS + +#### onFullscreenPlayerDidDismiss +Callback function that is called when the player has exited fullscreen mode. + +Payload: none + +Platforms: Android ExoPlayer, Android MediaPlayer, iOS + #### onLoad Callback function that is called when the media is loaded and ready to play. @@ -569,6 +590,34 @@ return ( ); ``` +#### dismissFullscreenPlayer +`dismissFullscreenPlayer()` + +Take the player out of fullscreen mode. + +Example: +``` +this.player.dismissFullscreenPlayer(); +``` + +Platforms: Android ExoPlayer, Android MediaPlayer, iOS + +#### FullscreenPlayer +`presentFullscreenPlayer()` + +Put the player in fullscreen mode. + +On iOS, this displays the video in a fullscreen view controller with controls. + +On Android ExoPlayer & MediaPlayer, this puts the navigation controls in fullscreen mode. It is not a complete fullscreen implementation, so you will still need to apply a style that makes the width and height match your screen dimensions to get a fullscreen video. + +Example: +``` +this.player.presentFullscreenPlayer(); +``` + +Platforms: Android ExoPlayer, Android MediaPlayer, iOS + #### seek() `seek(seconds)` From 18efffbd1a876e59dc1fdbefb5f00d7f2b958829 Mon Sep 17 00:00:00 2001 From: Hampton Maxwell Date: Tue, 17 Jul 2018 17:47:19 -0700 Subject: [PATCH 2/2] Implement hacky fullscreen This only handles the controls portion of fullscreen. It doesn't make the video use the entire screen, that still needs to be done via styles. Will be implemented later --- .../com/brentvatne/react/ReactVideoView.java | 46 ++++++++++++++++++- .../react/ReactVideoViewManager.java | 6 +++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/brentvatne/react/ReactVideoView.java b/android/src/main/java/com/brentvatne/react/ReactVideoView.java index 954130a155..7cc0aca323 100644 --- a/android/src/main/java/com/brentvatne/react/ReactVideoView.java +++ b/android/src/main/java/com/brentvatne/react/ReactVideoView.java @@ -1,6 +1,7 @@ package com.brentvatne.react; import android.annotation.SuppressLint; +import android.app.Activity; import android.content.res.AssetFileDescriptor; import android.graphics.Matrix; import android.media.MediaPlayer; @@ -9,6 +10,8 @@ import android.os.Handler; import android.util.Log; import android.view.MotionEvent; +import android.view.View; +import android.view.Window; import android.webkit.CookieManager; import android.widget.MediaController; @@ -46,7 +49,11 @@ public enum Events { EVENT_END("onVideoEnd"), EVENT_STALLED("onPlaybackStalled"), EVENT_RESUME("onPlaybackResume"), - EVENT_READY_FOR_DISPLAY("onReadyForDisplay"); + EVENT_READY_FOR_DISPLAY("onReadyForDisplay"), + EVENT_FULLSCREEN_WILL_PRESENT("onVideoFullscreenPlayerWillPresent"), + EVENT_FULLSCREEN_DID_PRESENT("onVideoFullscreenPlayerDidPresent"), + EVENT_FULLSCREEN_WILL_DISMISS("onVideoFullscreenPlayerWillDismiss"), + EVENT_FULLSCREEN_DID_DISMISS("onVideoFullscreenPlayerDidDismiss"); private final String mName; @@ -106,6 +113,7 @@ public String toString() { private float mActiveRate = 1.0f; private boolean mPlayInBackground = false; private boolean mBackgroundPaused = false; + private boolean mIsFullscreen = false; private int mMainVer = 0; private int mPatchVer = 0; @@ -208,6 +216,9 @@ public void cleanupMediaPlayerResources() { mMediaPlayerValid = false; release(); } + if (mIsFullscreen) { + setFullscreen(false); + } } public void setSrc(final String uriString, final String type, final boolean isNetwork, final boolean isAsset, final ReadableMap requestHeaders) { @@ -439,6 +450,39 @@ public void setRateModifier(final float rate) { } } + public void setFullscreen(boolean isFullscreen) { + if (isFullscreen == mIsFullscreen) { + return; // Avoid generating events when nothing is changing + } + mIsFullscreen = isFullscreen; + + Activity activity = mThemedReactContext.getCurrentActivity(); + if (activity == null) { + return; + } + Window window = activity.getWindow(); + View decorView = window.getDecorView(); + int uiOptions; + if (mIsFullscreen) { + if (Build.VERSION.SDK_INT >= 19) { // 4.4+ + uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION + | SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | SYSTEM_UI_FLAG_FULLSCREEN; + } else { + uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION + | SYSTEM_UI_FLAG_FULLSCREEN; + } + mEventEmitter.receiveEvent(getId(), Events.EVENT_FULLSCREEN_WILL_PRESENT.toString(), null); + decorView.setSystemUiVisibility(uiOptions); + mEventEmitter.receiveEvent(getId(), Events.EVENT_FULLSCREEN_DID_PRESENT.toString(), null); + } else { + uiOptions = View.SYSTEM_UI_FLAG_VISIBLE; + mEventEmitter.receiveEvent(getId(), Events.EVENT_FULLSCREEN_WILL_DISMISS.toString(), null); + decorView.setSystemUiVisibility(uiOptions); + mEventEmitter.receiveEvent(getId(), Events.EVENT_FULLSCREEN_DID_DISMISS.toString(), null); + } + } + public void applyModifiers() { setResizeModeModifier(mResizeMode); setRepeatModifier(mRepeat); diff --git a/android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java b/android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java index 7973121a57..dbf152a8e4 100644 --- a/android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java +++ b/android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java @@ -35,6 +35,7 @@ public class ReactVideoViewManager extends SimpleViewManager { public static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval"; public static final String PROP_SEEK = "seek"; public static final String PROP_RATE = "rate"; + public static final String PROP_FULLSCREEN = "fullscreen"; public static final String PROP_PLAY_IN_BACKGROUND = "playInBackground"; public static final String PROP_CONTROLS = "controls"; @@ -148,6 +149,11 @@ public void setRate(final ReactVideoView videoView, final float rate) { videoView.setRateModifier(rate); } + @ReactProp(name = PROP_FULLSCREEN, defaultBoolean = false) + public void setFullscreen(final ReactVideoView videoView, final boolean fullscreen) { + videoView.setFullscreen(fullscreen); + } + @ReactProp(name = PROP_PLAY_IN_BACKGROUND, defaultBoolean = false) public void setPlayInBackground(final ReactVideoView videoView, final boolean playInBackground) { videoView.setPlayInBackground(playInBackground);