sampotts / plyr

A simple HTML5, YouTube and Vimeo player
https://plyr.io
MIT License
26.59k stars 2.93k forks source link

clickthrough for youtube embed (title, share, more videos) #1321

Open vesper8 opened 5 years ago

vesper8 commented 5 years ago

When doing a regular youtube embed (not using Plyr) it's possible to interact with the UI (more videos, clicking on title to be brought to the youtube video on youtube.com, share button)

When loading through Plyr, all those UI elements show up but they are unclickable. Is there an option to allow the user to "click thru" the Plyr controls in order to interact with the underlying youtube UI?

Or is there a way to catch these events somehow to replicate the youtube UI behaviour? What I mean is, when a user clicks on a video from the 'more videos' (when paused or video is finished) rather than opening that video in another tab on youtube.com, we could catch it and open the video on the local site using Plyr?

I'm most interested in at least having a way to let the users click on the title and be brought to the original video, as is the behaviour of the normal non-plyr youtube embed

vesper8 commented 5 years ago

hrm... not sure if it was something I did.. but adding this fixed the problem

.plyr__video-embed iframe {
  /* this makes the ui clickable */
  z-index: 30;
}
Aduffy commented 5 years ago

This is what worked for me.

.plyr__video-embed iframe {
    pointer-events: all !important;
}
sampotts commented 5 years ago

It's a trade off. If you want click to play then we must be able to capture the click. Obviously a click on an <iframe> will be captured by the <iframe> unless pointer-events: none is set or we overlay an invisible element. It also effects other parts of the player including capturing hover events.

Aduffy commented 5 years ago

Thanks Sam, I seem to be getting the best of both worlds.. All PLYR elements clickable and hover events seem to be working plus all YT elements working.. Not been able to spot the down side yet.... am I missing something? (Now to figure out how to remove related videos showing on pause. )

sampotts commented 5 years ago

I tried your change and it didn't seem to make a difference in the demo. The poster image <div> is always overlaid over the <iframe> but will be opacity: 0;. This allows us to capture the pointer events. If that <div> is not there or display: none then we can't capture hover or click events. Your change to pointer-events: all isn't needed on the <iframe> as by default its value is auto anyway. We don't change this in CSS. Maybe you're using an older version?

antonyoneill commented 5 years ago

Hey @sampotts,

I have a use case for allowing the use of the YouTube controls instead of the Plyr controls.

We want our users to easily differentiate between a YouTube video, or a video we host on our website. We're offering features built on top of Plyr for our videos and want to reduce the subtlety between the two types of video.

We also want our users to be able to have a full YouTube experience (control captions, speed, quality, get to related videos, etc) while on our site.

In order to do that I could take the route of implementing a wrapper for the YouTube iframe API, or I can use Plyr without the controls.. The latter at face value seems much simpler, since we already have this wonderful library in place.

Unfortunately, using the options that I thought would be necessary, plus a bit of CSS to hide that poster – I find that the Plyr library does not allow YouTube to control the state of the Plyr. That is to say if I press Play inside YouTube, the resulting statechange event causes the Plyr to knee-jerk and emit a pause event almost immediately! :(

Example here: https://codepen.io/antonyoneill/pen/YzKmvjp

How do you feel about changing the logic introduced by #959, and accepting a Plyr state change via the YouTube statechange under the circumstance that Plyr has been configured with {youtube:{controls:1}}?

Look forward to your response!

onexdata commented 4 years ago

Not sure why this hasn't been addressed, but as of today, YouTube is actually drawing recommended videos at the bottom and showing the ability to subscribe to videos, add to watch later, etc,, and plyr is not hiding any of them, just disabling the ability to click anything, making the implementation look like it's just poorly implemented by plyr.

Here is the fix to stop plyr from disabling all the youtube stuff this till it's is addressed... It would be cool if the plyr__poster actually showed a poster, or didn't show... you know... either implement the feature or disable it?

let plyrPosterExists = document.getElementsByClassName('plyr__poster')
if (plyrPosterExists.length > 0) plyrPosterExists[0].style.display = 'none'
quangvhk commented 4 years ago

Hi @antonyoneill , I wonder if you found the solution for this use case. But I discovered a trick to solve it base on your code player.on('statechange', event => { const code = event.detail.code; if(code == 1) player.play(); }); It works for me to play video by youtube controls.

Ivanca commented 4 years ago

The closest thing I found to a solution is just to blur the video when is paused, unfortunately it blurs the title as well because its inside the youtube iframe:

.plyr iframe {
    transition: 0.2s filter linear;
}

.plyr.plyr--paused iframe {
    filter: blur(1.5rem);
} 
iamrobert commented 4 years ago

@Ivanca I did it this way:

https://codepen.io/iamrobert/pen/GRpZdQm

So the info bar is still visible on the screen.

antonyoneill commented 4 years ago

I'm sorry it's taken so long to get back to you, @quangvhk. From what I recall I wasn't able to find an adequate solution to the problem, but I didn't spend much more time on it.

The two solutions above may work :+1:

AlGantori commented 4 years ago

Personally in my use case, I do NOT want a click thru to happen, which connects anything with YouTube, NEVER, that's the reason I have been using plyr in the first place. My (family, children) audience

  1. should not be allowed to copy any link via Plyr, (let my app handle sharing).
  2. nor should the YouTube player jump to its website.

I cannot thank you enough @sampotts for maintaining this functionality.

In a previous .NET implementation against the YouTube API I had to overlay an opaque div, I think over the player, I am happy I don't have to do that with plyr.

jeff-hykin commented 3 years ago

I needed to see what was under the "more videos" section since our research sometimes needs to see that part of the video when going frame-by-frame while paused, so I needed both.

This did the trick for me, just getting the .plyr__poster out of the way. It keeps the functionality of both Plyr and YouTube

.plyr__poster {
    z-index: -1 !important;
}

The other CSS didn't work for me. @iamrobert's solution is visually really nice, if I didn't need to see the image when paused I would've gone with that.

jeff-hykin commented 3 years ago

@antonyoneill maybe there is a downside on different systems or event callbacks, but I'm unable to find one. I found the downsides: keyboard controls when clicking anything other than the Plyr buttons, and fullscreen works independently of Plyr causing problems when fullscreened. I still need to x-out the YouTube suggestions though so I'm just going to have to live with these things.

However, I found this solves about 80% of those issues

let focusWatcher = () => {
    let iframe = player.elements.wrapper.children[0]
    // we don't want to focus on the iframe ever
    if (document.activeElement == iframe) {
        // delayed recurse just as a check (but is necessary)
        setTimeout(focusWatcher, 0)
        // try focusing on the first form of the play button
        player.elements.buttons.play[0].focus()
        // or the second form as a backup
        player.elements.buttons.play[1].focus()
    }
}
window.addEventListener("focus",focusWatcher)
window.addEventListener("blur",focusWatcher)

Basically, every time the iframe is clicked, focus is only lost for that one moment. Immediately after the click, focus is sent back to the Plyr. The initial play action has an issue (which is solvable), and the fullscreen is still an issue (may not be solvable), but they're easily not noticed since people will likely click the play button when the video doesn't initially start. Being able to disable the native YouTube fullscreen would be very nice though, and its possible with their API.

Link Copy (after X-ing out the "more videos") Screen Shot 2020-12-03 at 7 19 34 PM

Using Plyer's speed controls Screen Shot 2020-12-03 at 7 19 24 PM