SvenTiigi / YouTubePlayerKit

A Swift Package to easily play YouTube videos 📺
https://sventiigi.github.io/YouTubePlayerKit/
MIT License
717 stars 64 forks source link

Reload webView after calling YouTubePlayer's load and cue functions #91

Closed acosmicflamingo closed 6 months ago

acosmicflamingo commented 6 months ago

Right now YouTubePlayer's statePublisher only sends its state downstream during the initial instance when YouTubePlayer's source is set. However, this does not ever happen again if load or cue is called with a new YouTubePlayer.Source value, making the statePublisher property unusable in its current state (no pun intended!).

acosmicflamingo commented 6 months ago

It appears this PR may fix statePublisher, but completely breaks playbackStatePublisher in the process.

acosmicflamingo commented 6 months ago

Alright, so here is what's happening. Let's say I initially cue a working YouTube video. I will get the following event changes:

statePublisher: ready An event has occurred: receivedJavaScriptEvent(YouTubePlayerKit.YouTubePlayer.JavaScriptEvent(name: YouTubePlayerKit.YouTubePlayer.JavaScriptEvent.Name.onStateChange, data: Optional("3")))

An event has occurred: receivedJavaScriptEvent(YouTubePlayerKit.YouTubePlayer.JavaScriptEvent(name: YouTubePlayerKit.YouTubePlayer.JavaScriptEvent.Name.onStateChange, data: Optional("5")))

An event has occurred: frameChanged((0.0, 0.0, 345.0, 235.33333333333331))

Then if I cue a link that results in an error, I get this:

statePublisher: ready An event has occurred: receivedJavaScriptEvent(YouTubePlayerKit.YouTubePlayer.JavaScriptEvent(name: YouTubePlayerKit.YouTubePlayer.JavaScriptEvent.Name.onStateChange, data: Optional("3")))

An event has occurred: receivedJavaScriptEvent(YouTubePlayerKit.YouTubePlayer.JavaScriptEvent(name: YouTubePlayerKit.YouTubePlayer.JavaScriptEvent.Name.onError, data: Optional("150"))) statePublisher: error(The owner of the requested video does not allow it to be played in embedded players.)

But if I cue a good link, I get this:

statePublisher: error(The owner of the requested video does not allow it to be played in embedded players.) An event has occurred: receivedJavaScriptEvent(YouTubePlayerKit.YouTubePlayer.JavaScriptEvent(name: YouTubePlayerKit.YouTubePlayer.JavaScriptEvent.Name.onStateChange, data: Optional("3")))

An event has occurred: receivedJavaScriptEvent(YouTubePlayerKit.YouTubePlayer.JavaScriptEvent(name: YouTubePlayerKit.YouTubePlayer.JavaScriptEvent.Name.onStateChange, data: Optional("5")))

Notice that "statePublisher: ready" didn't appear after the last .onStateChange event. What this means is that anything subscribed to playerStateSubject is going to initially receive the 'ready' event, and any time it receives the error event, it will never ever see playerState get back to the .ready state.

The reason this is happening is because playerStateSubject.send(.ready) is only called whenever the player does reach the .ready state, but you could have an instance where the .onStateChange case had playerState go from .error to .ready, in which case playerStateSubject should send a .ready event.

@SvenTiigi does this all sound right? I can try and create a PR that handles sending the latest playerState event in .onStateChange if you agree with this logic.