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

Youtube endless loading when embedding forbidden #1456

Open
Benny739 opened this issue Oct 5, 2024 · 7 comments
Open

Youtube endless loading when embedding forbidden #1456

Benny739 opened this issue Oct 5, 2024 · 7 comments
Labels
bug Something isn't working

Comments

@Benny739
Copy link

Benny739 commented Oct 5, 2024

Current Behavior:

When embedding is forbidden video shows an endless loading indicator with the poster
CleanShot 2024-10-05 at 20 47 52@2x

Expected Behavior:

The video can not be embedded image should be shown
CleanShot 2024-10-05 at 20 48 13@2x

Steps To Reproduce:

  1. Use a video where embedding is forbidden: https://www.youtube.com/watch?v=lpdfSB0iKAk

Reproduction Link: Demo Link

@Benny739 Benny739 added the bug Something isn't working label Oct 5, 2024
@yordandev
Copy link

I experienced the same and fixed it the following way:

    const handleProviderChange = (e: MediaProviderChangeEvent) => {
      const provider = e.detail;

      if (isYouTubeProvider(provider)) {
        provider.referrerPolicy = 'no-referrer-when-downgrade';
        provider.iframe.referrerPolicy = 'no-referrer-when-downgrade';
      }
    };

@Benny739
Copy link
Author

Benny739 commented Oct 7, 2024

Doesn't solve it for me, it still shows the poster with an endless loading indicator.

@brendanahart
Copy link

brendanahart commented Oct 10, 2024

Agreed, I still have the endless loading indicator on mine too. Is there any event that vidstack fires to show that a video cannot be played from YouTube. If so, then I'd like to just show a thumbnail

@brendanahart
Copy link

brendanahart commented Oct 24, 2024

I'm going to share my workaround and although it's not a solution, I think the reason why this is happening is because of the YouTube API. The full solution would have to be you render an iframe from a different URL (similar to how reddit plays youtube videos).

Essentially here is my MediaPlayer component:

        <MediaPlayer ...
           ref={playerRef}
        >
          <MediaProvider>
          ....
          </MediaProvider>
          <YoutubePlayerControl src={props.src} thumbnail={props.thumbnail} isExternal={props.isExternal} />
          <DefaultVideoLayout
          />
        </MediaPlayer>

Notice how I have a YoutubePlayerControl component there. I have a context hook that contains a reference to my video player in that component and use the bufferedEnd to see if the video has loaded. bufferedEnd is true when the video loads 1 second, however is false initially (0). If this video has not buffered 1 second that likely means it's blocked, which I then open the video up in the browser. This is my full code for my component:

const YoutubePlayerControl: React.FC<YoutubePlayerControlProps> = ({ src, isExternal, thumbnail }) => {
    const { playerRef } = useVideoContext();
    const bufferedEnd = useMediaState('bufferedEnd', playerRef);

    const openInBrowser = async () => {
        await Browser.open({ url: src, presentationStyle: 'popover' });
    };

    return (
        !bufferedEnd && isExternal && (
            <div
                className="absolute inset-0 w-full h-full cursor-pointer flex items-center justify-center"
                onClick={openInBrowser}
                aria-label="Youtube video"
            >
                {/* Icon container with higher z-index, using flex centering */}
                <div className="absolute z-30 flex items-center justify-center">
                    <IonImg
                        src="/assets/icon/logos--youtube-icon.svg"
                        alt="Play"
                        className="w-[100px] h-[100px]"
                    />
                </div>

                {/* Poster with lower z-index */}
                <Poster
                    className="absolute inset-0 block h-full w-full bg-black rounded-md opacity-0 transition-opacity data-[visible]:opacity-100 [&>img]:h-full [&>img]:w-full [&>img]:object-cover z-10"
                    src={thumbnail}
                />
            </div>
        )
    );
};

Hope this helps as I've been spending about 2 weeks thinking on how I can fix this and it works well enough for a good user experience!

@wplit
Copy link

wplit commented Oct 24, 2024

Hi @brendanahart,

Have you been able to get the player to be reliable for when using with YouTube? I'm still hitting lots of issues (reported but issues still exist), even with the default setup just following the docs exactly.

Especially when trying to view on iPhone. Finding it too unreliable for production. Lots of situations where the player still gets stuck. Some I've reported for where it reliably fails..

Setting playsinline=false prevents video from being playable on iPhone - #1431

The 'play' loading strategy will crash the player on iPhone (never ending loading, can't click to play ) - #1395

After using chapters to navigate, using the time slider no longer works and causes the player to get stuck - https://komododecks.com/recordings/92YAhFQn7wBvNDFaMKC0

Are these things you're using workarounds for? Are you seeing the same issues?

When I'm testing, these issues happen every time.

@brendanahart
Copy link

brendanahart commented Oct 25, 2024

Hey @wplit

I've never seen the player crash the app, however, I've seen the loading "Video is unavailable" whenever I try to load the video natively on an iPhone. I believe this is from the YouTube API blocking anything that is hosted on localhost (which by default is what an app is hosted on). It seems you must need an https connection to the video (according to this issue: https://stackoverflow.com/questions/51969269/embedded-youtube-video-doesnt-work-on-local-server). For some reason, randomly, videos are able to load sometimes and then not load natively on iOS. That's why I went with the custom thumbnail solution and then redirects them to a browser popup in app to load the youtube video. FYI I am using vidstack in a native iOS/Android app

I haven't gotten to chapters yet and the loading strategy I use is custom.

Here is my code. When the video loads, I am able to navigate with the timesliders.

I would make sure that on iPhone, you're audio is always muted unless you are native. That could be an issue. The user must make sure the audio is pressed for it to play according to recent authoritarian restrictions from Chrome and Safari

        <MediaPlayer
          ref={playerRef}
          src={props.src}
          poster={props.thumbnail}
          aspectRatio={aspectRatioFraction}
          crossOrigin
          playsInline
          loop
          paused={!shouldBePlaying}
          onCanPlay={handleCanPlay}
          onError={handleError}
          load="custom"
          posterLoad="eager"
          style={{ width: playerWidth }}
          onProviderChange={onProviderChange}
          className={loadingClass}
          onClick={handleMediaClick}
          muted={!isNative ? true : muted}
          controlsDelay={hasInteracted ? 1250 : 0}
        >
  useEffect(() => {
    // console.log("Scrolling:", props.isScrolling, "Speed:", props.scrollSpeed, "Should Load:", shouldLoad, "In View:", inView, "ID:", props.src);
    if (shouldLoad) {
      playerRef.current?.startLoading();
    }
  }, [inView, props.isScrolling, props.scrollSpeed]);

const shouldLoad = inView && (!props.isScrolling || props.scrollSpeed < playingScrollSpeedMax);

@wplit
Copy link

wplit commented Oct 27, 2024

I've never seen the player crash the app

Try setting the playsInline to false, and then view on iPhone. The player will crash the moment play is clicked (stuck in loading with no way to play the video).

Reg. mute being needed. Yes, this is a shame. It makes it less useful than a regular Youtube embed, which can play on one click. Obviously can't be helped from vidstack side of things, but is a huge UX issue imo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants