SvenTiigi / YouTubePlayerKit

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

Making WebView Public #76

Closed KeithComito closed 10 months ago

KeithComito commented 11 months ago

Having the WebView be public is useful in certain cases such as when you need to access its layer directly when integrating with other frameworks like SceneKit, ARKit, etc.

SvenTiigi commented 11 months ago

Hi @KeithComito,

Have you considered using either the YouTubePlayerViewController or the YouTubePlayerHostingView?

KeithComito commented 11 months ago

Hi @KeithComito,

Have you considered using either the YouTubePlayerViewController or the YouTubePlayerHostingView?

Hi @SvenTiigi yes - I tried those and they didn't work. To validate that the direct access to the WebViews layer was necessary I then created my own WKWebView (outside of your framework) to load a YouTube video and accessing its layer did work.

For example what I am doing in my case is - if myNode is an SCNNode -> myNode.geometry?.firstMaterial?.diffuse.contents = myWebView.layer which works.

Trying to do the same with any other view or layer (including of those you mentioned) did not work.

SvenTiigi commented 11 months ago

As the YouTubePlayerWebView class is internal there would be additional work required to refactor the webView property to public as well as other implications and side effects.

I recommend using the first subview (YouTubePlayerWebView) of the YouTubePlayerHostingView for this particular use case:

let view = YouTubePlayerHostingView(player: "https://youtube.com/....")
myNode.geometry?.firstMaterial?.diffuse.contents = view.subviews.first?.layer
KeithComito commented 11 months ago
let view = YouTubePlayerHostingView(player: "https://youtube.com/....")
myNode.geometry?.firstMaterial?.diffuse.contents = view.subviews.first?.layer

Hi Sven; thanks for the quick reply.

Interesting - this is a good workaround and does work - but only partially. I see the contents of YouTube on the SCNNode, but the actual content of the YouTube video itself is black. Strangely I do see the YouTube UI which overlays on top of the video (like the scrubbing bar or subscribe watermarks, etc. and at the end of the video I see the end cards and such), and hear the video playing after seeing the loading spinner resolve - but the actual content of the video itself is just rendering as black. Any thoughts?

Note: in my test example I'm first adding a the YouTubePlayerHostingView as a subview to my view controller and then executing the code above; which causes some autolayout warnings to appear (since I'm essentially stealing that subviews layer to put it into SceneKit node), but I don't see why any issues would affect only the YouTube video playback and leave all the surrounding and overlayed UI controls and YouTube overlay "cards" etc. in good shape. Preferably I'd like to not have to add the YouTubePlayerHostingView as a subview first, but I couldn't see how to get the video to play without doing this (even if I call play() on it manually) - leading me to believe something important is currently happening in the view lifecycle methods that do not happen if I never add YouTubePlayerHostingView as a subview (which, again; is something I don't want to do it in my case since I want to just add it to an SCNNode directly).

hstdt commented 11 months ago

A coincidence yesterday I create a fork for this too🤣🤣 and more public is necessary for compile error. https://github.com/hstdt/YouTubePlayerKit/commit/84b6fc27bfaa8dad72bc41a1f82afda601931e21

In my opinion, YouTubePlayerHostingView and YouTubePlayerViewController is difficult to add constraints and manage in view hierarchy, and act like a "singleton view" of youtube player.

PS: A public var for webview is also good way for approach. like this:

public var view: UIView {
    webView
}
KeithComito commented 10 months ago

Note: in my test example I'm first adding a the YouTubePlayerHostingView as a subview to my view controller and then executing the code above; which causes some autolayout warnings to appear (since I'm essentially stealing that subviews layer to put it into SceneKit node), but I don't see why any issues would affect only the YouTube video playback and leave all the surrounding and overlayed UI controls and YouTube overlay "cards" etc. in good shape. Preferably I'd like to not have to add the YouTubePlayerHostingView as a subview first, but I couldn't see how to get the video to play without doing this (even if I call play() on it manually) - leading me to believe something important is currently happening in the view lifecycle methods that do not happen if I never add YouTubePlayerHostingView as a subview (which, again; is something I don't want to do it in my case since I want to just add it to an SCNNode directly).

Hi @SvenTiigi ; just circling back. Dug into this more and I think what is happening above is that the AVPlayer is somehow being taken out of the view hierarchy (the WebAVPlayerLayerView) - which is why I see everything else, but not the actual video itself.

Then again, maybe the way I was doing it was too hamfisted -> If your goal was to just create a fresh Augmented Realty App type of project in Xcode w/ the SceneKit technology and have a YouTube video play on a node using your framework - how would you do it? Having your framework be able to work in this context (and also RealityKit Entities) would be quite valuable. Thanks!

SvenTiigi commented 10 months ago

Hi @KeithComito,

As this problem is related to the corresponding frameworks such as ARKit and SceneKit I would suggest searching or asking this question on other platforms such as the Apple Developer Forum or StackOverflow.

https://developer.apple.com/forums/thread/664566 https://stackoverflow.com/questions/51131318/can-arkit-display-wkwebview

KeithComito commented 10 months ago

@SvenTiigi Okay I am currently doing this - but this is actually a more general question that's relevant to your framework independent of those other specific frameworks -> that being can you add a way to interact with the video via AVPlayer / layer without requiring UIKit architecture (like adding it as a subview etc.)

I actually have this working beyond what the other posts have (in terms that i have the audio playing and other UI elements of YouTube showing - just not the video's AVPlayer displaying).

KeithComito commented 10 months ago

@SvenTiigi Okay I am currently doing this - but this is actually a more general question that's relevant to your framework independent of those other specific frameworks -> that being can you add a way to interact with the video via AVPlayer / layer without requiring UIKit architecture (like adding it as a subview etc.)

I actually have this working beyond what the other posts have (in terms that i have the audio playing and other UI elements of YouTube showing - just not the video's AVPlayer displaying).

@hstdt any thoughts on your end?

SvenTiigi commented 10 months ago

The YouTubePlayerKit does not make use of the AVFoundation Framework so there is no direct way in interacting with an instance of AVPlayer as the YouTube player is rendered in a WKWebView using the official YouTube Player iFrame API.

KeithComito commented 10 months ago

The YouTubePlayerKit does not make use of the AVFoundation Framework so there is no direct way in interacting with an instance of AVPlayer as the YouTube player is rendered in a WKWebView using the official YouTube Player iFrame API.

It's still addressable from this framework, because right now I can actually get my hands on the AVPlayer layer by crawling the view hierarchy - so I can force a solution, but it would be better if the framework actually did that implicitly and bubbled up a reference to the AVPlayerLayer that's being used.

If you want to verify this just inspect the view hierarchy while the app is running.

SvenTiigi commented 10 months ago

@KeithComito if you are traversing the view hierarchy, you will end up in traversing the view hierarchy of the underlying WKWebView which is developed and controlled by Apple and not by this framework.

For any additional inquiries, please refer to the previously mentioned platforms.

KeithComito commented 10 months ago

@KeithComito if you are traversing the view hierarchy, you will end up in traversing the view hierarchy of the underlying WKWebView which is developed and controlled by Apple and not by this framework.

For any additional inquiries, please refer to the previously mentioned platforms.

Yes I understand that. I'm saying that you can actually expose a reference to the underlying layer (that yes is created and supplied by the WKWebView framework), so that this reference would be simple for users of your Framework, instead of having users have to crawl the hierarchy and establish that reference manually. But it's okay if you don't want to do this - I just want to note for anyone reading later that attaining this reference and working with it is perfectly possible.

SvenTiigi commented 10 months ago

Please be reminded that this workaround may become ineffective in future releases of iOS, iPadOS, and macOS. Consequently, it is regarded as unstable, which is the reason why the YouTubePlayerKit does not provide an API for other developers.

KeithComito commented 10 months ago

Please be reminded that this workaround may become ineffective in future releases of iOS, iPadOS, and macOS. Consequently, it is regarded as unstable, which is the reason why the YouTubePlayerKit does not provide an API for other developers.

Makes sense; thanks!