Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS app crashes on call to presentFullScreenPlayer #2808

Closed
rafamanzo opened this issue Aug 7, 2022 · 9 comments · Fixed by #2971
Closed

iOS app crashes on call to presentFullScreenPlayer #2808

rafamanzo opened this issue Aug 7, 2022 · 9 comments · Fixed by #2971
Labels
help wanted The issue has been reviewed and is valid, and is waiting for someone to work on it. Platform: iOS

Comments

@rafamanzo
Copy link

Bug

When calling presentFullScreenPlayer in an iOS device/emulator (android is working perfectly) there is the following error:

Exception thrown while executing UI block: Application tried to present modally a view controller <RNSScreen: 0x7faff9950470> that has a parent view controller <RNScreensViewController: 0x7faff6a8fc50>.
__44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke
    RCTUIManager.m:1201
__44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke.498
__RCTExecuteOnMainQueue_block_invoke
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
-[UIApplication _run]
UIApplicationMain
main
start_sim
0x0

Which seem to me related to:

Our workaround for this currently is to not call the function at all in iOS and keep the controls enabled (controls={true}) which will provide a button to go fullscreen.

Platform

  • iOS

Environment info

React native info output:

info Fetching system and libraries information...
System:
    OS: macOS 12.3.1
    CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
    Memory: 29.54 MB / 8.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v16.15.1/bin/yarn
    npm: 8.11.0 - ~/.nvm/versions/node/v16.15.1/bin/npm
    Watchman: 2022.01.31.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.11.2 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.0.1, iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0
    Android SDK:
      API Levels: 31
      Build Tools: 31.0.0
      Android NDK: Not Found
  IDEs:
    Android Studio: Not Found
    Xcode: 13.1/13A1030d - /usr/bin/xcodebuild
  Languages:
    Java: Not Found
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2 
    react-native: 0.68.2 => 0.68.2 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Library version: 6.0.0.alpha1 (also tested in the top of master commit f32da09)

Steps To Reproduce

  1. call presentFullScreenPlayer on the video ref

...

Expected behaviour

  1. Present the fullscreen video

Reproducible sample code

videoRef?.presentFullScreenPlayer()
@ngima
Copy link

ngima commented Aug 11, 2022

For me I am getting same issue when controls={true}.

@jffun
Copy link

jffun commented Aug 19, 2022

For me, I export AVPlayerViewController+Fullscreen
and in RCTVideo.swift, add _controls check in setFullscreen method before present viewController

if _controls {
                    _playerViewController?.removeFromParent()
                    _playerViewController?.goFullscreen { [weak self] in
                        self?._playerViewController?.showsPlaybackControls = true
                        self?._playerViewController?.autorotate = self?._fullscreenAutorotate
                    }
                } else {
                viewController.present(viewController, animated:true, completion:{
                    self._playerViewController?.showsPlaybackControls = true
                    self._fullscreenPlayerPresented = fullscreen
                    self._playerViewController?.autorotate = self._fullscreenAutorotate
                    self.onVideoFullscreenPlayerDidPresent?(["target": self.reactTag])
                })
}

fixed this case

@freeboub freeboub added help wanted The issue has been reviewed and is valid, and is waiting for someone to work on it. Platform: iOS labels Aug 20, 2022
@bulkinav
Copy link

bulkinav commented Sep 7, 2022

@jffun maybe you can to create Pull request with your fixes?

@samonov22
Copy link

Changed viewController.present() functions argument from 'viewController' to '_playerViewController!' in setFullscreen method. Works for me.

@objc
    func setFullscreen(_ fullscreen:Bool) {
        if fullscreen && !_fullscreenPlayerPresented && _player != nil {
            // Ensure player view controller is not null
            if _playerViewController == nil {
                self.usePlayerViewController()
            } ...
if viewController != nil {
                _presentingViewController = viewController
                
                self.onVideoFullscreenPlayerWillPresent?(["target": reactTag as Any])

-               viewController.present(viewController, animated:true, completion:{                
+               viewController.present(_playerViewController!, animated:true, completion:{
                    self._playerViewController?.showsPlaybackControls = true
                    self._fullscreenPlayerPresented = fullscreen
                    self._playerViewController?.autorotate = self._fullscreenAutorotate
                    self.onVideoFullscreenPlayerDidPresent?(["target": self.reactTag])
                })
            }
        } ...

Path: node_modules/react-native-video/ios/Video/RCTVideo.swift
version: 6.0.0-alpha.3

@sahilcodedrill12
Copy link

sahilcodedrill12 commented Nov 3, 2022

@samonov22 there is lines as well can you please tell me about this as well?

var _playerViewController:UIViewController! = self.firstAvailableUIViewController()
if (_playerViewController == nil) {
let keyWindow:UIWindow! = UIApplication.shared.keyWindow
_playerViewController = keyWindow.rootViewController
if _playerViewController.children.count > 0
{
_playerViewController = _playerViewController.children.last
}
}

@bulkinav
Copy link

bulkinav commented Nov 6, 2022

Hi,

Can anyone confirm now that the problem is reproducible on iOS with the latest commits in master?

I can't reproduce the crash, but the player doesn't go to fullscreen either (how is this expected) - https://bulkin.me/files/ios_player.mov

This is very similar to the problem from #2864

My code:

const videoRef = useRef(null)

useEffect(() => {
        if (videoRef && videoRef?.current && videoRef?.current?.presentFullscreenPlayer) {
            videoRef?.current?.presentFullscreenPlayer()
        }
    }, [])

return (
        <View style={styles.container}>
            <Video
                ref={videoRef}
                source={{ uri }}
                onProgress={handleProgress}
                onEnd={handleEnd}
                controls={isNeedControls}
                fullscreen
                fullscreenOrientation="landscape"
                pictureInPicture
                style={StyleSheet.absoluteFill}
            />
        </View>
    )

@somersets
Copy link
Contributor

Hi, I had the same problem with the same version
@samonov22 and your suggestion helped me!

Changed viewController.present() functions argument from 'viewController' to '_playerViewController!' in setFullscreen method. Works for me.

@objc
    func setFullscreen(_ fullscreen:Bool) {
        if fullscreen && !_fullscreenPlayerPresented && _player != nil {
            // Ensure player view controller is not null
            if _playerViewController == nil {
                self.usePlayerViewController()
            } ...
if viewController != nil {
                _presentingViewController = viewController
                
                self.onVideoFullscreenPlayerWillPresent?(["target": reactTag as Any])

-               viewController.present(viewController, animated:true, completion:{                
+               viewController.present(_playerViewController!, animated:true, completion:{
                    self._playerViewController?.showsPlaybackControls = true
                    self._fullscreenPlayerPresented = fullscreen
                    self._playerViewController?.autorotate = self._fullscreenAutorotate
                    self.onVideoFullscreenPlayerDidPresent?(["target": self.reactTag])
                })
            }
        } ...

Path: node_modules/react-native-video/ios/Video/RCTVideo.swift version: 6.0.0-alpha.3

@johnbillion
Copy link
Contributor

@samonov22 @somersets This fix is working for us on alpha 4. Thank you! Do you want to open a PR?

@somersets
Copy link
Contributor

somersets commented Dec 20, 2022

@johnbillion Yes, I would like to open a PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted The issue has been reviewed and is valid, and is waiting for someone to work on it. Platform: iOS
Projects
None yet
9 participants