From 2cb4b4dd4fab918a13f2fefece14250a9afdd19f Mon Sep 17 00:00:00 2001 From: Ibrahim Sulaiman Date: Wed, 28 Aug 2019 01:29:19 +0530 Subject: [PATCH 01/10] Added the full screen functionality to the android Exoplayer control --- Video.js | 78 +++++++++++------- .../exoplayer/ReactExoplayerView.java | 47 ++++++++++- .../main/res/drawable/fullscreen_expand.png | Bin 0 -> 365 bytes .../main/res/drawable/fullscreen_shrink.png | Bin 0 -> 358 bytes .../res/layout/exo_player_control_view.xml | 16 ++++ 5 files changed, 108 insertions(+), 33 deletions(-) create mode 100644 android-exoplayer/src/main/res/drawable/fullscreen_expand.png create mode 100644 android-exoplayer/src/main/res/drawable/fullscreen_shrink.png diff --git a/Video.js b/Video.js index 474d7b269d..ea80cb2f3f 100644 --- a/Video.js +++ b/Video.js @@ -1,6 +1,6 @@ -import React, {Component} from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import {StyleSheet, requireNativeComponent, NativeModules, View, ViewPropTypes, Image, Platform, findNodeHandle} from 'react-native'; +import { StyleSheet, requireNativeComponent, NativeModules, View, ViewPropTypes, Image, Platform, findNodeHandle, Dimensions } from 'react-native'; import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; import TextTrackType from './TextTrackType'; import FilterType from './FilterType'; @@ -20,24 +20,25 @@ export default class Video extends Component { super(props); this.state = { - showPoster: !!props.poster + showPoster: !!props.poster, + androidFullScreen: false }; } setNativeProps(nativeProps) { this._root.setNativeProps(nativeProps); } - + toTypeString(x) { switch (typeof x) { case "object": - return x instanceof Date - ? x.toISOString() + return x instanceof Date + ? x.toISOString() : JSON.stringify(x); // object, null case "undefined": return ""; default: // boolean, number, string - return x.toString(); + return x.toString(); } } @@ -53,7 +54,7 @@ export default class Video extends Component { seek = (time, tolerance = 100) => { if (isNaN(time)) throw new Error('Specified time is not a number'); - + if (Platform.OS === 'ios') { this.setNativeProps({ seek: { @@ -88,7 +89,7 @@ export default class Video extends Component { _hidePoster = () => { if (this.state.showPoster) { - this.setState({showPoster: false}); + this.setState({ showPoster: false }); } } @@ -124,7 +125,7 @@ export default class Video extends Component { if (this.props.onBandwidthUpdate) { this.props.onBandwidthUpdate(event.nativeEvent); } - }; + }; _onSeek = (event) => { if (this.props.onSeek) { @@ -145,6 +146,7 @@ export default class Video extends Component { }; _onFullscreenPlayerWillPresent = (event) => { + Platform.OS === 'android' && this.setState({ androidFullScreen: true }) if (this.props.onFullscreenPlayerWillPresent) { this.props.onFullscreenPlayerWillPresent(event.nativeEvent); } @@ -157,6 +159,7 @@ export default class Video extends Component { }; _onFullscreenPlayerWillDismiss = (event) => { + Platform.OS === 'android' && this.setState({ androidFullScreen: false }) if (this.props.onFullscreenPlayerWillDismiss) { this.props.onFullscreenPlayerWillDismiss(event.nativeEvent); } @@ -192,7 +195,7 @@ export default class Video extends Component { this.props.onPlaybackRateChange(event.nativeEvent); } }; - + _onExternalPlaybackChange = (event) => { if (this.props.onExternalPlaybackChange) { this.props.onExternalPlaybackChange(event.nativeEvent); @@ -212,7 +215,7 @@ export default class Video extends Component { }; _onRestoreUserInterfaceForPictureInPictureStop = (event) => { - if (this.props.onRestoreUserInterfaceForPictureInPictureStop) { + if (this.props.onRestoreUserInterfaceForPictureInPictureStop) { this.props.onRestoreUserInterfaceForPictureInPictureStop(); } }; @@ -245,7 +248,7 @@ export default class Video extends Component { if (uri && uri.match(/^\//)) { uri = `file://${uri}`; } - + if (!uri) { console.warn('Trying to load empty source.'); } @@ -267,8 +270,19 @@ export default class Video extends Component { } const nativeProps = Object.assign({}, this.props); + //androidFullScreen property will only impact on android. It will be always false for iOS. + const videoStyle = this.state.androidFullScreen ? { + position: 'absolute', + top: 0, + left: 0, + width: Math.round(Dimensions.get('window').width), + height: Math.round(Dimensions.get('window').height), + backgroundColor: 'transparent', + justifyContent: "center", + zIndex: 99999 + } : {} Object.assign(nativeProps, { - style: [styles.base, nativeProps.style], + style: [styles.base, nativeProps.style, videoStyle], resizeMode: nativeResizeMode, src: { uri, @@ -327,22 +341,22 @@ export default class Video extends Component { Video.propTypes = { filter: PropTypes.oneOf([ - FilterType.NONE, - FilterType.INVERT, - FilterType.MONOCHROME, - FilterType.POSTERIZE, - FilterType.FALSE, - FilterType.MAXIMUMCOMPONENT, - FilterType.MINIMUMCOMPONENT, - FilterType.CHROME, - FilterType.FADE, - FilterType.INSTANT, - FilterType.MONO, - FilterType.NOIR, - FilterType.PROCESS, - FilterType.TONAL, - FilterType.TRANSFER, - FilterType.SEPIA + FilterType.NONE, + FilterType.INVERT, + FilterType.MONOCHROME, + FilterType.POSTERIZE, + FilterType.FALSE, + FilterType.MAXIMUMCOMPONENT, + FilterType.MINIMUMCOMPONENT, + FilterType.CHROME, + FilterType.FADE, + FilterType.INSTANT, + FilterType.MONO, + FilterType.NOIR, + FilterType.PROCESS, + FilterType.TONAL, + FilterType.TRANSFER, + FilterType.SEPIA ]), filterEnabled: PropTypes.bool, /* Native only */ @@ -396,7 +410,7 @@ Video.propTypes = { PropTypes.string, PropTypes.number ]) - }), + }), selectedTextTrack: PropTypes.shape({ type: PropTypes.string.isRequired, value: PropTypes.oneOfType([ @@ -437,7 +451,7 @@ Video.propTypes = { audioOnly: PropTypes.bool, currentTime: PropTypes.number, fullscreenAutorotate: PropTypes.bool, - fullscreenOrientation: PropTypes.oneOf(['all','landscape','portrait']), + fullscreenOrientation: PropTypes.oneOf(['all', 'landscape', 'portrait']), progressUpdateInterval: PropTypes.number, useTextureView: PropTypes.bool, hideShutterView: PropTypes.bool, diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 1edb8c7ac2..e177055c18 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -3,6 +3,7 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; +import android.content.pm.ActivityInfo; import android.media.AudioManager; import android.net.Uri; import android.os.Handler; @@ -13,6 +14,7 @@ import android.view.Window; import android.view.accessibility.CaptioningManager; import android.widget.FrameLayout; +import android.widget.ImageView; import com.brentvatne.react.R; import com.brentvatne.receiver.AudioBecomingNoisyReceiver; @@ -298,6 +300,17 @@ public void onClick(View v) { } }); + //Handling the fullScreenButton click event + FrameLayout fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen_button); + fullScreenButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + //Play the video whenever the user clicks minimize or maximise button. In order to enable the controls + player.setPlayWhenReady(true); + updateFullScreenIcon(isFullscreen); + } + }); + // Invoking onPlayerStateChanged event for Player eventListener = new Player.EventListener() { @Override @@ -326,6 +339,32 @@ private void addPlayerControl() { addView(playerControlView, 1, layoutParams); } + /** + * Update fullscreen icon + */ + private void updateFullScreenIcon(Boolean fullScreen) { + if(playerControlView != null) { + ImageView fullScreenIcon = playerControlView.findViewById(R.id.exo_fullscreen_icon); + if (isFullscreen) { + fullScreenIcon.setImageResource(R.drawable.fullscreen_expand); + } else { + fullScreenIcon.setImageResource(R.drawable.fullscreen_shrink); + } + setFullscreen(!isFullscreen); + } + } + + /** + * Enable or Disable fullscreen button + */ + private void enableFullScreenButton(Boolean enable) { + if(playerControlView != null) { + FrameLayout fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen_button); + fullScreenButton.setAlpha(enable ? 1.0f : 0.5f); + fullScreenButton.setEnabled(enable); + } + } + /** * Update the layout * @param view view needs to update layout @@ -530,10 +569,13 @@ private void stopPlayback() { private void onStopPlayback() { if (isFullscreen) { - setFullscreen(false); + //When the video stopPlayback. + //If the video is in fullscreen, then we will update the video to normal mode. + updateFullScreenIcon(isFullscreen); } setKeepScreenOn(false); audioManager.abandonAudioFocus(this); + enableFullScreenButton(false); } private void updateResumePosition() { @@ -620,6 +662,7 @@ public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { if(playerControlView != null) { playerControlView.show(); } + enableFullScreenButton(true); break; case ExoPlayer.STATE_ENDED: text += "ended"; @@ -1143,11 +1186,13 @@ public void setFullscreen(boolean fullscreen) { uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_FULLSCREEN; } + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); eventEmitter.fullscreenWillPresent(); decorView.setSystemUiVisibility(uiOptions); eventEmitter.fullscreenDidPresent(); } else { uiOptions = View.SYSTEM_UI_FLAG_VISIBLE; + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); eventEmitter.fullscreenWillDismiss(); decorView.setSystemUiVisibility(uiOptions); eventEmitter.fullscreenDidDismiss(); diff --git a/android-exoplayer/src/main/res/drawable/fullscreen_expand.png b/android-exoplayer/src/main/res/drawable/fullscreen_expand.png new file mode 100644 index 0000000000000000000000000000000000000000..f94cd81e83cdd8cd06be67209f58050532d84b01 GIT binary patch literal 365 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSY)RhkE)4%caKYZ?lYt_f1s;*b z3=GW2K$x-lmOUd-kiEpy*OmPtCku;=ra{p!AE3}LPZ!6Kid%2*So1X~2)G8$`+fiO z4o1%$ABpF4uC+bjo!=G`x^~&5CoP2~^A2Yl&SGF`U=Uz1PAzY;ecEz%ySb=#gDwN3 z0z{a}fq{c$4g)%P&>IqJTj!Bf^)LDR{JnxEa~N1ab~2G;I8aZ+;vD&|9K#>Za+}}S hw1+W7gH38^%;Wl|urlrTkp31lF&-Yo(Vqj@t5MW?(VBlb2RA68sk<$=%?fL}g zZ@w1M<_+p#0~j#Cmx(8vl_oDaY^OGVp<-aWFxZL*KC4gr|LWiWhBN&&+XoiXZ3bHg cHfq6Cc79Qrt<3%=7eID + + + + + From 67e4c6fa9fe6bea2ff6cb94b839b5b0d449dace9 Mon Sep 17 00:00:00 2001 From: Ibrahim Sulaiman Date: Wed, 28 Aug 2019 02:25:43 +0530 Subject: [PATCH 02/10] Added the margin attribute in full screen mode --- Video.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Video.js b/Video.js index ea80cb2f3f..c669192687 100644 --- a/Video.js +++ b/Video.js @@ -279,7 +279,11 @@ export default class Video extends Component { height: Math.round(Dimensions.get('window').height), backgroundColor: 'transparent', justifyContent: "center", - zIndex: 99999 + zIndex: 99999, + marginLeft: 0, //margin: 0 - is not working properly. So, updated all the margin individually with 0. + marginRight: 0, + marginTop: 0, + marginBottom: 0 } : {} Object.assign(nativeProps, { style: [styles.base, nativeProps.style, videoStyle], From b89d19737c5d38bebd2a336bd65f5e9dffe5e772 Mon Sep 17 00:00:00 2001 From: Ibrahim Sulaiman Date: Wed, 28 Aug 2019 16:33:58 +0530 Subject: [PATCH 03/10] Handled the fullScreen props from the react native --- .../exoplayer/ReactExoplayerView.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index e177055c18..a067f6fcb0 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -305,11 +305,10 @@ public void onClick(View v) { fullScreenButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - //Play the video whenever the user clicks minimize or maximise button. In order to enable the controls - player.setPlayWhenReady(true); - updateFullScreenIcon(isFullscreen); + setFullscreen(!isFullscreen); } }); + updateFullScreenIcon(isFullscreen); // Invoking onPlayerStateChanged event for Player eventListener = new Player.EventListener() { @@ -343,14 +342,15 @@ private void addPlayerControl() { * Update fullscreen icon */ private void updateFullScreenIcon(Boolean fullScreen) { - if(playerControlView != null) { + if(playerControlView != null && player != null) { + //Play the video whenever the user clicks minimize or maximise button. In order to enable the controls + player.setPlayWhenReady(true); ImageView fullScreenIcon = playerControlView.findViewById(R.id.exo_fullscreen_icon); - if (isFullscreen) { - fullScreenIcon.setImageResource(R.drawable.fullscreen_expand); - } else { + if (fullScreen) { fullScreenIcon.setImageResource(R.drawable.fullscreen_shrink); + } else { + fullScreenIcon.setImageResource(R.drawable.fullscreen_expand); } - setFullscreen(!isFullscreen); } } @@ -571,7 +571,7 @@ private void onStopPlayback() { if (isFullscreen) { //When the video stopPlayback. //If the video is in fullscreen, then we will update the video to normal mode. - updateFullScreenIcon(isFullscreen); + setFullscreen(!isFullscreen); } setKeepScreenOn(false); audioManager.abandonAudioFocus(this); @@ -1168,6 +1168,8 @@ public void setFullscreen(boolean fullscreen) { if (fullscreen == isFullscreen) { return; // Avoid generating events when nothing is changing } + + updateFullScreenIcon(fullscreen); isFullscreen = fullscreen; Activity activity = themedReactContext.getCurrentActivity(); From 55b7ac7951eda98e9d39063bbb0837ac34368d0a Mon Sep 17 00:00:00 2001 From: Ibrahim Sulaiman Date: Wed, 28 Aug 2019 17:11:12 +0530 Subject: [PATCH 04/10] Moved the video style to the root container which includes poster --- Video.js | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/Video.js b/Video.js index c669192687..a7a5f211da 100644 --- a/Video.js +++ b/Video.js @@ -270,23 +270,8 @@ export default class Video extends Component { } const nativeProps = Object.assign({}, this.props); - //androidFullScreen property will only impact on android. It will be always false for iOS. - const videoStyle = this.state.androidFullScreen ? { - position: 'absolute', - top: 0, - left: 0, - width: Math.round(Dimensions.get('window').width), - height: Math.round(Dimensions.get('window').height), - backgroundColor: 'transparent', - justifyContent: "center", - zIndex: 99999, - marginLeft: 0, //margin: 0 - is not working properly. So, updated all the margin individually with 0. - marginRight: 0, - marginTop: 0, - marginBottom: 0 - } : {} Object.assign(nativeProps, { - style: [styles.base, nativeProps.style, videoStyle], + style: [styles.base, nativeProps.style], resizeMode: nativeResizeMode, src: { uri, @@ -328,8 +313,24 @@ export default class Video extends Component { resizeMode: this.props.posterResizeMode || 'contain', }; + //androidFullScreen property will only impact on android. It will be always false for iOS. + const videoStyle = this.state.androidFullScreen ? { + position: 'absolute', + top: 0, + left: 0, + width: Math.round(Dimensions.get('window').width), + height: Math.round(Dimensions.get('window').height), + backgroundColor: '#ffffff', + justifyContent: "center", + zIndex: 99999, + marginLeft: 0, //margin: 0 - is not working properly. So, updated all the margin individually with 0. + marginRight: 0, + marginTop: 0, + marginBottom: 0 + } : {} + return ( - + Date: Wed, 28 Aug 2019 20:33:33 +0530 Subject: [PATCH 05/10] Resolved the flickering issue while rotating the screen --- Video.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Video.js b/Video.js index a7a5f211da..208c07ca75 100644 --- a/Video.js +++ b/Video.js @@ -23,6 +23,21 @@ export default class Video extends Component { showPoster: !!props.poster, androidFullScreen: false }; + this.getDimension(); + } + + /** + * @description this is will set the width and height needs to be considered for full screen + */ + getDimension() { + if (Dimensions.get('window').width < Dimensions.get('window').height) { + this.width = Math.round(Dimensions.get('window').height); + this.height = Math.round(Dimensions.get('window').width); + } + else { + this.width = Math.round(Dimensions.get('window').width); + this.height = Math.round(Dimensions.get('window').height); + } } setNativeProps(nativeProps) { @@ -318,8 +333,8 @@ export default class Video extends Component { position: 'absolute', top: 0, left: 0, - width: Math.round(Dimensions.get('window').width), - height: Math.round(Dimensions.get('window').height), + width: this.width, + height: this.height, backgroundColor: '#ffffff', justifyContent: "center", zIndex: 99999, From 913e76344db4bd6102c2fc845317a8b3068e0dba Mon Sep 17 00:00:00 2001 From: Ibrahim Sulaiman Date: Fri, 20 Sep 2019 13:15:23 +0530 Subject: [PATCH 06/10] Handled the Margins related to the absolute position for the video container --- Video.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Video.js b/Video.js index 208c07ca75..d716793bb6 100644 --- a/Video.js +++ b/Video.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { StyleSheet, requireNativeComponent, NativeModules, View, ViewPropTypes, Image, Platform, findNodeHandle, Dimensions } from 'react-native'; +import { StyleSheet, requireNativeComponent, NativeModules, View, ViewPropTypes, Image, Platform, UIManager, findNodeHandle, Dimensions } from 'react-native'; import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; import TextTrackType from './TextTrackType'; import FilterType from './FilterType'; @@ -21,7 +21,9 @@ export default class Video extends Component { this.state = { showPoster: !!props.poster, - androidFullScreen: false + androidFullScreen: false, + videoContainerLayout_x: 0, + videoContainerLayout_y: 0 }; this.getDimension(); } @@ -40,6 +42,15 @@ export default class Video extends Component { } } + componentDidMount() { + UIManager.measure(findNodeHandle(this._videoContainer), (x, y) => { + this.setState({ + videoContainerLayout_x: x, + videoContainerLayout_y: y + }) + }) + } + setNativeProps(nativeProps) { this._root.setNativeProps(nativeProps); } @@ -338,14 +349,12 @@ export default class Video extends Component { backgroundColor: '#ffffff', justifyContent: "center", zIndex: 99999, - marginLeft: 0, //margin: 0 - is not working properly. So, updated all the margin individually with 0. - marginRight: 0, - marginTop: 0, - marginBottom: 0 + marginTop: -1 * (this.state.videoContainerLayout_y ? parseFloat(this.state.videoContainerLayout_y) : 0), //margin: 0 - is not working properly. So, updated all the margin individually with 0. + marginLeft: -1 * (this.state.videoContainerLayout_x ? parseFloat(this.state.videoContainerLayout_x) : 0) } : {} return ( - + this._videoContainer = videoContainer} style={[nativeProps.style, videoStyle]}> Date: Wed, 9 Oct 2019 16:16:13 +0530 Subject: [PATCH 07/10] Initial orientation is restored and updated to the activity in the setFullscreen method --- .../java/com/brentvatne/exoplayer/ReactExoplayerView.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 27e9c9005c..ecf7e577d2 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -99,6 +99,7 @@ class ReactExoplayerView extends FrameLayout implements private Player.EventListener eventListener; private ExoPlayerView exoPlayerView; + private int initialOrientation; private DataSource.Factory mediaDataSourceFactory; private SimpleExoPlayer player; @@ -171,6 +172,7 @@ public void handleMessage(Message msg) { public ReactExoplayerView(ThemedReactContext context, ReactExoplayerConfig config) { super(context); this.themedReactContext = context; + this.initialOrientation = getResources().getConfiguration().orientation; this.eventEmitter = new VideoEventEmitter(context); this.config = config; this.bandwidthMeter = config.getBandwidthMeter(); @@ -1229,7 +1231,11 @@ public void setFullscreen(boolean fullscreen) { eventEmitter.fullscreenDidPresent(); } else { uiOptions = View.SYSTEM_UI_FLAG_VISIBLE; - activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + //orientation, 1 is for Portrait and 2 for Landscape. + if(this.initialOrientation == 1) + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + else + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); eventEmitter.fullscreenWillDismiss(); decorView.setSystemUiVisibility(uiOptions); eventEmitter.fullscreenDidDismiss(); From 71509c2ea7a3a8ae8931d8f77aa1ff25f161cfed Mon Sep 17 00:00:00 2001 From: Ibrahim Sulaiman Date: Sat, 12 Oct 2019 23:24:05 +0530 Subject: [PATCH 08/10] Updated the changelog and readme file --- CHANGELOG.md | 3 +++ README.md | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d410045dd2..e9ea180b3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## Changelog +### Version 5.1.1 +* Added support for full-screen functionality in Android Exoplayer [#1730](https://github.com/react-native-community/react-native-video/pull/1730) + ### Version 5.1.0-alpha1 * Fixed Exoplayer doesn't work with mute=true (Android). [#1696](https://github.com/react-native-community/react-native-video/pull/1696) * Added support for automaticallyWaitsToMinimizeStalling property (iOS) [#1723](https://github.com/react-native-community/react-native-video/pull/1723) diff --git a/README.md b/README.md index 964aa9043f..76d6394709 100644 --- a/README.md +++ b/README.md @@ -412,6 +412,8 @@ Note on iOS, controls are always shown when in fullscreen mode. For Android MediaPlayer, you will need to build your own controls or use a package like [react-native-video-controls](https://github.com/itsnubix/react-native-video-controls) or [react-native-video-player](https://github.com/cornedor/react-native-video-player). +Note on Android ExoPlayer, native controls are available by default. If needed, you can also add your controls or use a package like [react-native-video-controls]. + Platforms: Android ExoPlayer, iOS, react-native-dom #### disableFocus @@ -462,7 +464,7 @@ Controls whether the player enters fullscreen on play. * **false (default)** - Don't display the video in fullscreen * **true** - Display the video in fullscreen -Platforms: iOS +Platforms: iOS, Android Exoplayer #### fullscreenAutorotate If a preferred [fullscreenOrientation](#fullscreenorientation) is set, causes the video to rotate to that orientation but permits rotation of the screen to orientation held by user. Defaults to TRUE. @@ -475,6 +477,8 @@ Platforms: iOS * **landscape** * **portrait** +Note on Android ExoPlayer, the full-screen mode by default goes into landscape mode. Exiting from the full-screen mode will display the video in Initial orientation. + Platforms: iOS #### headers From e683dd382a0ab98d2a2b3076cf4334e027ba7289 Mon Sep 17 00:00:00 2001 From: Ibrahim Sulaiman Date: Sat, 7 Dec 2019 01:57:57 +0530 Subject: [PATCH 09/10] Updated the orientation to sensor lanscape orientation --- .../main/java/com/brentvatne/exoplayer/ReactExoplayerView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index ecf7e577d2..52f7567f16 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -1225,7 +1225,7 @@ public void setFullscreen(boolean fullscreen) { uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_FULLSCREEN; } - activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); eventEmitter.fullscreenWillPresent(); decorView.setSystemUiVisibility(uiOptions); eventEmitter.fullscreenDidPresent(); From b257727f2e0a7ab10ed886fb2d740f5a5c439c06 Mon Sep 17 00:00:00 2001 From: Ibrahim Sulaiman Date: Wed, 19 Feb 2020 13:04:50 +0530 Subject: [PATCH 10/10] Added the logic to control the play and pause on the fullscreen functionality --- .../exoplayer/ReactExoplayerView.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index a03b0fbba5..e6dcc186d7 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -14,6 +14,7 @@ import android.view.Window; import android.view.accessibility.CaptioningManager; import android.widget.FrameLayout; +import android.widget.ImageButton; import android.widget.ImageView; import com.brentvatne.react.R; @@ -296,6 +297,27 @@ public void onClick(View v) { } }); + //Handling the playButton click event + ImageButton playButton = playerControlView.findViewById(R.id.exo_play); + playButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (player != null && player.getPlaybackState() == Player.STATE_ENDED) { + player.seekTo(0); + } + setPausedModifier(false); + } + }); + + //Handling the pauseButton click event + ImageButton pauseButton = playerControlView.findViewById(R.id.exo_pause); + pauseButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + setPausedModifier(true); + } + }); + //Handling the fullScreenButton click event FrameLayout fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen_button); fullScreenButton.setOnClickListener(new View.OnClickListener() { @@ -340,7 +362,7 @@ private void addPlayerControl() { private void updateFullScreenIcon(Boolean fullScreen) { if(playerControlView != null && player != null) { //Play the video whenever the user clicks minimize or maximise button. In order to enable the controls - player.setPlayWhenReady(true); + player.setPlayWhenReady(!isPaused); ImageView fullScreenIcon = playerControlView.findViewById(R.id.exo_fullscreen_icon); if (fullScreen) { fullScreenIcon.setImageResource(R.drawable.fullscreen_shrink);