Merge pull request #3230 from iFeelSmart/fix/presentFullscreenPlayerImplementation

fix: implement lost presentFullscreenPlayer & dismissFullscreenPlayer
This commit is contained in:
Olivier Bouillet 2023-09-05 18:48:17 +02:00 committed by GitHub
commit 267181be73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 3 deletions

4
API.md
View File

@ -551,10 +551,12 @@ Platforms: Android
#### fullscreen
Controls whether the player enters fullscreen on play.
See [presentFullscreenPlayer](#presentfullscreenplayer) for details.
* **false (default)** - Don't display the video in fullscreen
* **true** - Display the video in fullscreen
Platforms: iOS
Platforms: iOS, Android
#### 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.

View File

@ -40,6 +40,8 @@ class VideoPlayer extends Component {
this.onProgress = this.onProgress.bind(this);
this.onBuffer = this.onBuffer.bind(this);
}
video = React.createRef();
state = {
rate: 1,
volume: 1,
@ -155,6 +157,20 @@ class VideoPlayer extends Component {
)
}
renderFullscreenControl(fullscreen: string) {
return (
<TouchableOpacity onPress={() => {
if (fullscreen === 'fullscreen') {
this.video.presentFullscreenPlayer()
}
}}>
<Text style={[styles.controlOption]}>
{fullscreen}
</Text>
</TouchableOpacity>
)
}
renderMixWithOthersControl(mixWithOthers: string) {
const isSelected = (this.state.mixWithOthers == mixWithOthers);
@ -175,6 +191,9 @@ class VideoPlayer extends Component {
<View style={styles.container}>
<TouchableOpacity style={styles.fullScreen} onPress={() => {this.setState({paused: !this.state.paused})}}>
<Video
ref={(ref: Video) => {
this.video = ref
}}
source={require('./broadchurch.mp4')}
style={styles.fullScreen}
rate={this.state.rate}
@ -248,6 +267,9 @@ class VideoPlayer extends Component {
{this.renderMixWithOthersControl('mix')}
{this.renderMixWithOthersControl('duck')}
</View>
<View style={styles.mixWithOthersControl}>
{this.renderFullscreenControl('fullscreen')}
</View>
</> : null
}
</View>

View File

@ -679,7 +679,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
func setFullscreen(_ fullscreen:Bool) {
if fullscreen && !_fullscreenPlayerPresented && _player != nil {
// Ensure player view controller is not null
if _playerViewController == nil && _controls {
// Controls will be displayed even if it is disabled in configuration
if _playerViewController == nil {
self.usePlayerViewController()
}
@ -709,7 +710,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
viewController.present(playerViewController, animated:true, completion:{ [weak self] in
guard let self = self else {return}
self._playerViewController?.showsPlaybackControls = self._controls
// In fullscreen we must display controls
self._playerViewController?.showsPlaybackControls = true
self._fullscreenPlayerPresented = fullscreen
self._playerViewController?.autorotate = self._fullscreenAutorotate
@ -988,6 +990,14 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
_resouceLoaderDelegate?.setLicenseResultError(error)
}
func dismissFullscreenPlayer(_ error:String!) {
setFullscreen(false)
}
func presentFullscreenPlayer(_ error:String!) {
setFullscreen(true)
}
// MARK: - RCTPlayerObserverHandler
func handleTimeUpdate(time:CMTime) {

View File

@ -73,4 +73,10 @@ RCT_EXTERN_METHOD(setLicenseResult:(NSString *)license
RCT_EXTERN_METHOD(setLicenseResultError(NSString *)error
reactTag:(nonnull NSNumber *)reactTag)
RCT_EXTERN_METHOD(presentFullscreenPlayer
reactTag:(nonnull NSNumber *)reactTag)
RCT_EXTERN_METHOD(dismissFullscreenPlayer
reactTag:(nonnull NSNumber *)reactTag)
@end

View File

@ -48,6 +48,29 @@ class RCTVideoManager: RCTViewManager {
})
}
@objc(dismissFullscreenPlayer:reactTag:)
func dismissFullscreenPlayer(error: NSString, reactTag: NSNumber) -> Void {
bridge.uiManager.prependUIBlock({_ , viewRegistry in
let view = viewRegistry?[reactTag]
if !(view is RCTVideo) {
RCTLogError("Invalid view returned from registry, expecting RCTVideo, got: %@", String(describing: view))
} else if let view = view as? RCTVideo {
view.dismissFullscreenPlayer(error as String)
}
})
}
@objc(presentFullscreenPlayer:reactTag:)
func presentFullscreenPlayer(error: NSString, reactTag: NSNumber) -> Void {
bridge.uiManager.prependUIBlock({_ , viewRegistry in
let view = viewRegistry?[reactTag]
if !(view is RCTVideo) {
RCTLogError("Invalid view returned from registry, expecting RCTVideo, got: %@", String(describing: view))
} else if let view = view as? RCTVideo {
view.presentFullscreenPlayer(error as String)
}
})
}
override func constantsToExport() -> [AnyHashable : Any]? {
return [
"ScaleNone": AVLayerVideoGravity.resizeAspect,