Support preventsDisplaySleepDuringVideoPlayback (#2019)

* Add flag on iOS

* Add flag in Android

* Add documentation

* Add changelog entry

* Also set setKeepScreenOn

* Fix prop not being set

* add preventsDisplaySleepDuringVideoPlayback to exoplayer

* Update android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java

* Update android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java

Co-authored-by: Jens Andersson <jens@fritan.com>

Co-authored-by: Anton Tanderup <antontandrup@gmail.com>
Co-authored-by: Jens Andersson <jens@fritan.com>
This commit is contained in:
Anders Lemke 2020-06-16 14:31:23 +02:00 committed by GitHub
parent 9c31948dbf
commit 8962720f56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 63 additions and 5 deletions

View File

@ -9,6 +9,7 @@
- Added `preferredForwardBufferDuration` (iOS) - the duration the player should buffer media from the network ahead of the playhead to guard against playback disruption. (#1944) - Added `preferredForwardBufferDuration` (iOS) - the duration the player should buffer media from the network ahead of the playhead to guard against playback disruption. (#1944)
- Added `currentPlaybackTime` (Android ExoPlayer, iOS) - when playing an HLS live stream with a `EXT-X-PROGRAM-DATE-TIME` tag configured, then this property will contain the epoch value in msec. (#1944) - Added `currentPlaybackTime` (Android ExoPlayer, iOS) - when playing an HLS live stream with a `EXT-X-PROGRAM-DATE-TIME` tag configured, then this property will contain the epoch value in msec. (#1944)
- Added `trackId` (Android ExoPlayer) - Configure an identifier for the video stream to link the playback context to the events emitted. (#1944) - Added `trackId` (Android ExoPlayer) - Configure an identifier for the video stream to link the playback context to the events emitted. (#1944)
- Added preventsDisplaySleepDuringVideoPlayback (#2019)
- Reverted the JS fullscreening for Android. [#2013](https://github.com/react-native-community/react-native-video/pull/2013) - Reverted the JS fullscreening for Android. [#2013](https://github.com/react-native-community/react-native-video/pull/2013)
- Set iOS request headers without needing to edit RCTVideo.m. [#2014](https://github.com/react-native-community/react-native-video/pull/2014) - Set iOS request headers without needing to edit RCTVideo.m. [#2014](https://github.com/react-native-community/react-native-video/pull/2014)

View File

@ -299,6 +299,7 @@ var styles = StyleSheet.create({
* [poster](#poster) * [poster](#poster)
* [posterResizeMode](#posterresizemode) * [posterResizeMode](#posterresizemode)
* [preferredForwardBufferDuration](#preferredForwardBufferDuration) * [preferredForwardBufferDuration](#preferredForwardBufferDuration)
* [preventsDisplaySleepDuringVideoPlayback](#preventsDisplaySleepDuringVideoPlayback)
* [progressUpdateInterval](#progressupdateinterval) * [progressUpdateInterval](#progressupdateinterval)
* [rate](#rate) * [rate](#rate)
* [repeat](#repeat) * [repeat](#repeat)
@ -607,6 +608,13 @@ Default: 0
Platforms: iOS Platforms: iOS
#### preventsDisplaySleepDuringVideoPlayback
Controls whether or not the display should be allowed to sleep while playing the video. Default is not to allow display to sleep.
Default: true
Platforms: iOS, Android
#### progressUpdateInterval #### progressUpdateInterval
Delay in milliseconds between onProgress events in milliseconds. Delay in milliseconds between onProgress events in milliseconds.

View File

@ -136,6 +136,7 @@ class ReactExoplayerView extends FrameLayout implements
private Dynamic textTrackValue; private Dynamic textTrackValue;
private ReadableArray textTracks; private ReadableArray textTracks;
private boolean disableFocus; private boolean disableFocus;
private boolean preventsDisplaySleepDuringVideoPlayback = true;
private float mProgressUpdateInterval = 250.0f; private float mProgressUpdateInterval = 250.0f;
private boolean playInBackground = false; private boolean playInBackground = false;
private Map<String, String> requestHeaders; private Map<String, String> requestHeaders;
@ -564,7 +565,7 @@ class ReactExoplayerView extends FrameLayout implements
initializePlayer(); initializePlayer();
} }
if (!disableFocus) { if (!disableFocus) {
setKeepScreenOn(true); setKeepScreenOn(preventsDisplaySleepDuringVideoPlayback);
} }
} }
@ -586,7 +587,6 @@ class ReactExoplayerView extends FrameLayout implements
if (isFullscreen) { if (isFullscreen) {
setFullscreen(false); setFullscreen(false);
} }
setKeepScreenOn(false);
audioManager.abandonAudioFocus(this); audioManager.abandonAudioFocus(this);
} }
@ -670,11 +670,15 @@ class ReactExoplayerView extends FrameLayout implements
text += "idle"; text += "idle";
eventEmitter.idle(); eventEmitter.idle();
clearProgressMessageHandler(); clearProgressMessageHandler();
if (!playWhenReady) {
setKeepScreenOn(false);
}
break; break;
case Player.STATE_BUFFERING: case Player.STATE_BUFFERING:
text += "buffering"; text += "buffering";
onBuffering(true); onBuffering(true);
clearProgressMessageHandler(); clearProgressMessageHandler();
setKeepScreenOn(preventsDisplaySleepDuringVideoPlayback);
break; break;
case Player.STATE_READY: case Player.STATE_READY:
text += "ready"; text += "ready";
@ -686,11 +690,13 @@ class ReactExoplayerView extends FrameLayout implements
if (playerControlView != null) { if (playerControlView != null) {
playerControlView.show(); playerControlView.show();
} }
setKeepScreenOn(preventsDisplaySleepDuringVideoPlayback);
break; break;
case Player.STATE_ENDED: case Player.STATE_ENDED:
text += "ended"; text += "ended";
eventEmitter.end(); eventEmitter.end();
onStopPlayback(); onStopPlayback();
setKeepScreenOn(false);
break; break;
default: default:
text += "unknown"; text += "unknown";
@ -1003,6 +1009,10 @@ class ReactExoplayerView extends FrameLayout implements
this.repeat = repeat; this.repeat = repeat;
} }
public void setPreventsDisplaySleepDuringVideoPlayback(boolean preventsDisplaySleepDuringVideoPlayback) {
this.preventsDisplaySleepDuringVideoPlayback = preventsDisplaySleepDuringVideoPlayback;
}
public void setSelectedTrack(int trackType, String type, Dynamic value) { public void setSelectedTrack(int trackType, String type, Dynamic value) {
if (player == null) return; if (player == null) return;
int rendererIndex = getTrackRendererIndex(trackType); int rendererIndex = getTrackRendererIndex(trackType);

View File

@ -44,6 +44,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_BUFFER_CONFIG_MAX_BUFFER_MS = "maxBufferMs"; private static final String PROP_BUFFER_CONFIG_MAX_BUFFER_MS = "maxBufferMs";
private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_MS = "bufferForPlaybackMs"; private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_MS = "bufferForPlaybackMs";
private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = "bufferForPlaybackAfterRebufferMs"; private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = "bufferForPlaybackAfterRebufferMs";
private static final String PROP_PREVENTS_DISPLAY_SLEEP_DURING_VIDEO_PLAYBACK = "preventsDisplaySleepDuringVideoPlayback";
private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval"; private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval";
private static final String PROP_REPORT_BANDWIDTH = "reportBandwidth"; private static final String PROP_REPORT_BANDWIDTH = "reportBandwidth";
private static final String PROP_SEEK = "seek"; private static final String PROP_SEEK = "seek";
@ -150,6 +151,11 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
videoView.setRepeatModifier(repeat); videoView.setRepeatModifier(repeat);
} }
@ReactProp(name = PROP_PREVENTS_DISPLAY_SLEEP_DURING_VIDEO_PLAYBACK, defaultBoolean = false)
public void setPreventsDisplaySleepDuringVideoPlayback(final ReactExoplayerView videoView, final boolean preventsSleep) {
videoView.setPreventsDisplaySleepDuringVideoPlayback(preventsSleep);
}
@ReactProp(name = PROP_SELECTED_VIDEO_TRACK) @ReactProp(name = PROP_SELECTED_VIDEO_TRACK)
public void setSelectedVideoTrack(final ReactExoplayerView videoView, public void setSelectedVideoTrack(final ReactExoplayerView videoView,
@Nullable ReadableMap selectedVideoTrack) { @Nullable ReadableMap selectedVideoTrack) {

View File

@ -123,6 +123,7 @@ public class ReactVideoView extends ScalableVideoView implements
private boolean mRepeat = false; private boolean mRepeat = false;
private boolean mPaused = false; private boolean mPaused = false;
private boolean mMuted = false; private boolean mMuted = false;
private boolean mPreventsDisplaySleepDuringVideoPlayback = true;
private float mVolume = 1.0f; private float mVolume = 1.0f;
private float mStereoPan = 0.0f; private float mStereoPan = 0.0f;
private float mProgressUpdateInterval = 250.0f; private float mProgressUpdateInterval = 250.0f;
@ -210,7 +211,6 @@ public class ReactVideoView extends ScalableVideoView implements
if (mMediaPlayer == null) { if (mMediaPlayer == null) {
mMediaPlayerValid = false; mMediaPlayerValid = false;
mMediaPlayer = new MediaPlayer(); mMediaPlayer = new MediaPlayer();
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setOnVideoSizeChangedListener(this); mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setOnErrorListener(this); mMediaPlayer.setOnErrorListener(this);
mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnPreparedListener(this);
@ -410,7 +410,7 @@ public class ReactVideoView extends ScalableVideoView implements
mProgressUpdateHandler.post(mProgressUpdateRunnable); mProgressUpdateHandler.post(mProgressUpdateRunnable);
} }
} }
setKeepScreenOn(!mPaused); setKeepScreenOn(!mPaused && mPreventsDisplaySleepDuringVideoPlayback);
} }
// reduces the volume based on stereoPan // reduces the volume based on stereoPan
@ -421,6 +421,17 @@ public class ReactVideoView extends ScalableVideoView implements
return roundRelativeVolume.floatValue(); return roundRelativeVolume.floatValue();
} }
public void setPreventsDisplaySleepDuringVideoPlaybackModifier(final boolean preventsDisplaySleepDuringVideoPlayback) {
mPreventsDisplaySleepDuringVideoPlayback = preventsDisplaySleepDuringVideoPlayback;
if (!mMediaPlayerValid) {
return;
}
mMediaPlayer.setScreenOnWhilePlaying(mPreventsDisplaySleepDuringVideoPlayback);
setKeepScreenOn(mPreventsDisplaySleepDuringVideoPlayback);
}
public void setMutedModifier(final boolean muted) { public void setMutedModifier(final boolean muted) {
mMuted = muted; mMuted = muted;
@ -517,6 +528,7 @@ public class ReactVideoView extends ScalableVideoView implements
setRepeatModifier(mRepeat); setRepeatModifier(mRepeat);
setPausedModifier(mPaused); setPausedModifier(mPaused);
setMutedModifier(mMuted); setMutedModifier(mMuted);
setPreventsDisplaySleepDuringVideoPlaybackModifier(mPreventsDisplaySleepDuringVideoPlayback);
setProgressUpdateInterval(mProgressUpdateInterval); setProgressUpdateInterval(mProgressUpdateInterval);
setRateModifier(mRate); setRateModifier(mRate);
} }
@ -712,7 +724,7 @@ public class ReactVideoView extends ScalableVideoView implements
else { else {
setSrc(mSrcUriString, mSrcType, mSrcIsNetwork, mSrcIsAsset, mRequestHeaders); setSrc(mSrcUriString, mSrcType, mSrcIsNetwork, mSrcIsAsset, mRequestHeaders);
} }
setKeepScreenOn(true); setKeepScreenOn(mPreventsDisplaySleepDuringVideoPlayback);
} }
@Override @Override

View File

@ -30,6 +30,7 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {
public static final String PROP_REPEAT = "repeat"; public static final String PROP_REPEAT = "repeat";
public static final String PROP_PAUSED = "paused"; public static final String PROP_PAUSED = "paused";
public static final String PROP_MUTED = "muted"; public static final String PROP_MUTED = "muted";
public static final String PROP_PREVENTS_DISPLAY_SLEEP_DURING_VIDEO_PLAYBACK = "preventsDisplaySleepDuringVideoPlayback";
public static final String PROP_VOLUME = "volume"; public static final String PROP_VOLUME = "volume";
public static final String PROP_STEREO_PAN = "stereoPan"; public static final String PROP_STEREO_PAN = "stereoPan";
public static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval"; public static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval";
@ -104,6 +105,11 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {
} }
} }
@ReactProp(name = PROP_PREVENTS_DISPLAY_SLEEP_DURING_VIDEO_PLAYBACK)
public void setPropPreventsDisplaySleepDuringVideoPlayback(final ReactVideoView videoView, final boolean doPreventSleep) {
videoView.setPreventsDisplaySleepDuringVideoPlaybackModifier(doPreventSleep);
}
@ReactProp(name = PROP_RESIZE_MODE) @ReactProp(name = PROP_RESIZE_MODE)
public void setResizeMode(final ReactVideoView videoView, final String resizeModeOrdinalString) { public void setResizeMode(final ReactVideoView videoView, final String resizeModeOrdinalString) {
videoView.setResizeModeModifier(ScalableType.values()[Integer.parseInt(resizeModeOrdinalString)]); videoView.setResizeModeModifier(ScalableType.values()[Integer.parseInt(resizeModeOrdinalString)]);

View File

@ -64,6 +64,7 @@ static int const RCTVideoUnset = -1;
NSDictionary * _selectedAudioTrack; NSDictionary * _selectedAudioTrack;
BOOL _playbackStalled; BOOL _playbackStalled;
BOOL _playInBackground; BOOL _playInBackground;
BOOL _preventsDisplaySleepDuringVideoPlayback;
float _preferredForwardBufferDuration; float _preferredForwardBufferDuration;
BOOL _playWhenInactive; BOOL _playWhenInactive;
BOOL _pictureInPicture; BOOL _pictureInPicture;
@ -106,6 +107,7 @@ static int const RCTVideoUnset = -1;
_controls = NO; _controls = NO;
_playerBufferEmpty = YES; _playerBufferEmpty = YES;
_playInBackground = false; _playInBackground = false;
_preventsDisplaySleepDuringVideoPlayback = true;
_preferredForwardBufferDuration = 0.0f; _preferredForwardBufferDuration = 0.0f;
_allowsExternalPlayback = YES; _allowsExternalPlayback = YES;
_playWhenInactive = false; _playWhenInactive = false;
@ -815,6 +817,12 @@ static int const RCTVideoUnset = -1;
_playInBackground = playInBackground; _playInBackground = playInBackground;
} }
- (void)setPreventsDisplaySleepDuringVideoPlayback:(BOOL)preventsDisplaySleepDuringVideoPlayback
{
_preventsDisplaySleepDuringVideoPlayback = preventsDisplaySleepDuringVideoPlayback;
[self applyModifiers];
}
- (void)setAllowsExternalPlayback:(BOOL)allowsExternalPlayback - (void)setAllowsExternalPlayback:(BOOL)allowsExternalPlayback
{ {
_allowsExternalPlayback = allowsExternalPlayback; _allowsExternalPlayback = allowsExternalPlayback;
@ -1021,6 +1029,12 @@ static int const RCTVideoUnset = -1;
[_player setVolume:_volume]; [_player setVolume:_volume];
[_player setMuted:NO]; [_player setMuted:NO];
} }
if (@available(iOS 12.0, *)) {
self->_player.preventsDisplaySleepDuringVideoPlayback = _preventsDisplaySleepDuringVideoPlayback;
} else {
// Fallback on earlier versions
}
[self setMaxBitRate:_maxBitRate]; [self setMaxBitRate:_maxBitRate];
[self setSelectedAudioTrack:_selectedAudioTrack]; [self setSelectedAudioTrack:_selectedAudioTrack];

View File

@ -32,6 +32,7 @@ RCT_EXPORT_VIEW_PROPERTY(muted, BOOL);
RCT_EXPORT_VIEW_PROPERTY(controls, BOOL); RCT_EXPORT_VIEW_PROPERTY(controls, BOOL);
RCT_EXPORT_VIEW_PROPERTY(volume, float); RCT_EXPORT_VIEW_PROPERTY(volume, float);
RCT_EXPORT_VIEW_PROPERTY(playInBackground, BOOL); RCT_EXPORT_VIEW_PROPERTY(playInBackground, BOOL);
RCT_EXPORT_VIEW_PROPERTY(preventsDisplaySleepDuringVideoPlayback, BOOL);
RCT_EXPORT_VIEW_PROPERTY(preferredForwardBufferDuration, float); RCT_EXPORT_VIEW_PROPERTY(preferredForwardBufferDuration, float);
RCT_EXPORT_VIEW_PROPERTY(playWhenInactive, BOOL); RCT_EXPORT_VIEW_PROPERTY(playWhenInactive, BOOL);
RCT_EXPORT_VIEW_PROPERTY(pictureInPicture, BOOL); RCT_EXPORT_VIEW_PROPERTY(pictureInPicture, BOOL);