SvenTiigi / YouTubePlayerKit

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

Player not loading in scrollview #67

Closed justmv closed 1 year ago

justmv commented 1 year ago

What happened?

When I put

ScrollView() {
        YouTubePlayerView(
            "https://youtube.com/watch?v=psL_5RIBqnY"
        )
}

It does not load the player. If I enable auto-play, the sound plays but the video is not rendered. Targeting iOS 16

What are the steps to reproduce?

Put the player in a ScrollView

What is the expected behavior?

The player to load the video

SvenTiigi commented 1 year ago

Hi @justmv,

Did you try to add a frame modifier to specify the height?

ScrollView() {
    YouTubePlayerView(
        "https://youtube.com/watch?v=psL_5RIBqnY"
    )
    .frame(height: 220)
}
justmv commented 1 year ago

Hey @SvenTiigi, that worked! I still have a few issues that I'm trying to resolve tho. I'm building a carousel and displaying multiple players inside a LazyVStack and:

  1. Some of the players don't always load, I need to scroll them out of view then in view again for them to load
  2. When a player is playing it is blocking the scrolling function of the scroll view, i.e. I can't start scrolling when starting the scrolling movement from the video, is that intended or am I doing something wrong?

P.S Thanks for the awesome lib!

SvenTiigi commented 1 year ago

Without actually seeing your implementation I guess that by using LazyVStack SwiftUI will constantly re-render the cells/content of the LazyVStack so you need to make sure to retain the YouTubePlayer by using @StateObject otherwise the YouTubePlayer will always be re-instantiated which might be the reason why the player view always seems to reload.

Additionally, please be aware that simultaneous playback of multiple YouTube players is not supported.

justmv commented 1 year ago

@SvenTiigi here's the code - I'm using state for the players

@State var players: [YouTubePlayer] = []

func createPlayer(youtubeVideo: GetYoutubeChannelContentResponseItem) -> YouTubePlayerView<_ConditionalContent<_ConditionalContent<ProgressView<EmptyView, EmptyView>, EmptyView>, Text>> {
        let player = YouTubePlayer(
            source: .url(youtubeVideo.link),
            configuration: youtubePlayerConfig)
        players.append(player)

        return YouTubePlayerView(player) { state in
            // Overlay ViewBuilder closure to place an overlay View
            // for the current `YouTubePlayer.State`
            switch state {
            case .idle:
                ProgressView()
            case .ready:
                EmptyView()
            case .error(let _error):
                Text(verbatim: "YouTube player couldn't be loaded")
            }
        }
    }

ScrollView(.vertical, showsIndicators: false) {
    LazyVStack(alignment: .leading) {
        ForEach(items, id: \.id) { youtubeVideo in
             createPlayer(youtubeVideo: youtubeVideo)
        }
    }
}

The progress view is shown and then just a black background