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,