youtube / youtube-ios-player-helper

Lightweight helper library that allows iOS developers to add inline playback of YouTube videos through a WebView
Other
1.64k stars 680 forks source link

Fix bug that full screen playback is not possible on iPad #452

Open harumidiv opened 2 years ago

harumidiv commented 2 years ago

Overview

Fixed it not working when tapping the default full screen button on the iPad.

gsl-adriensimon commented 2 years ago

When will these changes be released?

Janneman84 commented 1 year ago

This 'fix' makes videos always play full screen, instead of optional...

Instead I found a workaround to fool YouTube by creating a small UIWindow (375x375pt) and add the YT player as a subview to that window (same size). After the video is loaded (using the delegate callback) I move the player view to my desired view by simply using addSubview(). You don't have to make the UIWindow visible, just keep a reference to it so it won't deinit (i.e. a VC property).

I noticed when you use iPad split screen and make the app as thin as possible then the YT player does allow full screen (but only when it starts when thin). When you make it big again the full screen button keeps working. This helped me realize it may be possible to trick YT like I explained above, which works :).

I found that 375pt is the threshold, if you make the UIWindow 376pt the full screen button stops working.

If interested I can show some code.

aryanarayantiwari commented 11 months ago

This 'fix' makes videos always play full screen, instead of optional...

Instead I found a workaround to fool YouTube by creating a small UIWindow (375x375pt) and add the YT player as a subview to that window (same size). After the video is loaded (using the delegate callback) I move the player view to my desired view by simply using addSubview(). You don't have to make the UIWindow visible, just keep a reference to it so it won't deinit (i.e. a VC property).

I noticed when you use iPad split screen and make the app as thin as possible then the YT player does allow full screen (but only when it starts when thin). When you make it big again the full screen button keeps working. This helped me realize it may be possible to trick YT like I explained above, which works :).

I found that 375pt is the threshold, if you make the UIWindow 376pt the full screen button stops working.

If interested I can show some code.

Hi! @Janneman84 can you please share some code for what you just specified ?

Janneman84 commented 11 months ago

Hi! @Janneman84 can you please share some code for what you just specified ?

Inside ViewController declare:

private var hackWindow: UIWindow?

Initiate the player like this:

if (UIDevice().userInterfaceIdiom == .pad) {
    let playerView = YTPlayerView(frame: CGRect(x: 0, y: 0, width: 375, height: 375))
    hackWindow = UIWindow.init(frame: playerView.frame)
    hackWindow!.addSubview(playerView)
    playerView.delegate = self
    playerView.load(...)
}

Implement delegate method like this:

func playerViewDidBecomeReady(_ playerView: YTPlayerView) {
    if let hackedPlayerView = hackWindow?.subviews.first as? YTPlayerView, hackedPlayerView == playerView {
        hackedPlayerView.frame = myVideoView.bounds
        myVideoView.addSubview(hackedPlayerView)
        hackWindow = nil
    }
    playerView.playVideo()
}


I haven't tested this exact code but you get the idea. In the delegate you can add/insert the player view wherever you want.

aryanarayantiwari commented 11 months ago

Hi! @Janneman84 can you please share some code for what you just specified ?

Inside ViewController declare:

private var hackWindow: UIWindow?

Initiate the player like this:

if (UIDevice().userInterfaceIdiom == .pad) {
    let playerView = YTPlayerView(frame: CGRect(x: 0, y: 0, width: 375, height: 375))
    hackWindow = UIWindow.init(frame: playerView.frame)
    hackWindow!.addSubview(playerView)
    playerView.delegate = self
    playerView.load(...)
}

Implement delegate method like this:

func playerViewDidBecomeReady(_ playerView: YTPlayerView) {
    if let hackedPlayerView = hackWindow?.subviews.first as? YTPlayerView, hackedPlayerView == playerView {
        hackedPlayerView.frame = myVideoView.bounds
        myVideoView.addSubview(hackedPlayerView)
        hackWindow = nil
    }
    playerView.playVideo()
}


I haven't tested this exact code but you get the idea. In the delegate you can add/insert the player view wherever you want.

Thanks! this works perfectly.