diff --git a/API.md b/API.md index 85badf38..760b9651 100644 --- a/API.md +++ b/API.md @@ -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. diff --git a/examples/basic/src/VideoPlayer.ios.tsx b/examples/basic/src/VideoPlayer.ios.tsx index 74025104..b8d916c5 100644 --- a/examples/basic/src/VideoPlayer.ios.tsx +++ b/examples/basic/src/VideoPlayer.ios.tsx @@ -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 ( + { + if (fullscreen === 'fullscreen') { + this.video.presentFullscreenPlayer() + } + }}> + + {fullscreen} + + + ) + } + renderMixWithOthersControl(mixWithOthers: string) { const isSelected = (this.state.mixWithOthers == mixWithOthers); @@ -175,6 +191,9 @@ class VideoPlayer extends Component { {this.setState({paused: !this.state.paused})}}> + + {this.renderFullscreenControl('fullscreen')} + : null } diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index 03ae306d..166aae6c 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -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) { diff --git a/ios/Video/RCTVideoManager.m b/ios/Video/RCTVideoManager.m index bf00cb45..7880a89f 100644 --- a/ios/Video/RCTVideoManager.m +++ b/ios/Video/RCTVideoManager.m @@ -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 diff --git a/ios/Video/RCTVideoManager.swift b/ios/Video/RCTVideoManager.swift index d1c73de8..bfdec7a4 100644 --- a/ios/Video/RCTVideoManager.swift +++ b/ios/Video/RCTVideoManager.swift @@ -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,