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

Reuse players (to circumvent Chrome autoplay issues) #12

Closed
wants to merge 6 commits into from

Conversation

Fauntleroy
Copy link
Contributor

Why

Google Chrome recently implemented a new feature to protect users from tabs that maliciously autoplay audio content. This feature ensures that only tabs/windows that have had focus in the past can autoplay. A side effect of this issue is that the YouTube and Vimeo players (in react-player) can no longer autoplay if the tab/window isn't focused, even if that tab/window had focus in the past. This is because react-player currently creates and destroys new iframes every time the source url changes. In order to have YouTube and Vimeo play properly while the user is in another tab/window, a change had to be made.

What I did

  • Changed react-player to a render/show system rather than selective rendering. Every player is rendered, but only one player is shown at a time.
  • Adjusted logic where necessary to enable the player to work with this new approach
  • Updated the tests
  • Added a "delay 5 seconds" checkbox to the test page

How to verify

  • Pull this branch
  • npm run start
  • http://localhost:3000/
  • Play a YouTube video
  • Play a SoundCloud song
  • Check the "delay 5 seconds" checkbox
  • Play a YouTube video, then immediately switch to another tab
  • After 5 seconds the YouTube player should play, even though the tab is not focused

Notes

  • Maybe switch to a load & play system. Right now videos/sound are just played right away. Might want to have a "loaded" state where we just do something like cueVideoByUrl
  • There might be some dead code that still needs to be sniffed out
  • Clean up Vimeo iframe situation

@cookpete
Copy link
Owner

Thanks for the PR. I might take a look and attempt a slightly less disruptive fix for this (before I start getting anal and we go back and forth reviewing this PR) but this is definitely a good start. I appreciate the effort!

@cookpete
Copy link
Owner

So, this fixes one use case, but doesn't quite fix the problem entirely. I still need to "prime" the player with a youtube video for it to autoplay when I queue one up later. My use case, for example:

  • Mount a fresh ReactPlayer with props.onEnded set to load('http://www.youtube...')
  • Play a Soundcloud track and seek to the end
  • Focus on another tab before the Soundcloud track ends
  • When the track ends, the youtube video should then play

My current thoughts for a proper fix are:

  • Render all players from the start
  • For Youtube and Vimeo, autoplay a blank/silent video on mount
  • As soon as an onPlay event occurs, immediately pause the video, then the players are "primed" and truly ready to play media, either now or later when out of focus.

Not the cleanest of solutions, but this is the best I can think of right now, and something I'll work on this week. Rendering all players at once has it's own problems that need sorting too.

@cookpete
Copy link
Owner

I've attempted an alternative, more thorough fix in #13

@ioRekz
Copy link

ioRekz commented Dec 15, 2015

Just to be clear as I'm trying to fixe the same issue on my project where I use clojurescript.
With React-player, if one youtube song follow another youtube song, the iframe is not recreated, and the YT player plays the new videoId.
If I understand correctly, in that case, the video will autoplay even without tab focus.

In my project, I'm only playing youtube video and I'm not recreating the iframe (shouldComponentupdate false and using new props) and yet the player wait for the focus to play again ...

I read the react player code and I don't see any big difference in the way to play another video so I'm asking if you have any idea of what could go wrong. Thanks !

@Fauntleroy
Copy link
Contributor Author

@ioRekz if the url prop is ever null, I believe the problem would still happen. Does that ever happen?

@ioRekz
Copy link

ioRekz commented Dec 15, 2015

Not in my case no :(

On Tue, Dec 15, 2015 at 5:22 PM, Timothy Kempf [email protected]
wrote:

@ioRekz https://github.com/ioRekz if the url prop is ever null, I
believe the problem would still happen. Does that ever happen?


Reply to this email directly or view it on GitHub
#12 (comment).

@cookpete
Copy link
Owner

@ioRekz from your question it sounds like you aren't actually using ReactPlayer but are just asking for help with the Youtube player API in general? Correct me if I'm wrong.

Note that using shouldComponentupdate doesn't actually achieve much in the way of the youtube player, as it is created and handled outside of react (by the new YT.Player global object). If you are doing new YT.Player(options) every time you play a video (instead of storing the player and using loadVideoById for subsequent video loads) then I believe this will reload the frame and reset the autoplay permissions, causing the issues you describe.

If I am mistaken and you are in fact using ReactPlayer, hopefully when #13 lands this problem will be resolved.

@ioRekz
Copy link

ioRekz commented Dec 15, 2015

No I'm not because I'm using a wrapper around React from clojurescript and
don't have access to react-player. I actually store the YT player and I
double checked that the iframe is not recreated.

So yes I'm not using React player right now, but I will as soon as I can
use it from my cljs project.
So this is a mix between getting help and understanding the player/iframe
behaviour.

On Tue, Dec 15, 2015 at 5:29 PM, Pete Cook [email protected] wrote:

@ioRekz https://github.com/ioRekz from your question it sounds like you
aren't actually using ReactPlayer but are just asking for help with the
Youtube player API in general? Correct me if I'm wrong.

Note that using shouldComponentupdate doesn't actually achieve much in
the way of the youtube player, as it is created and handled outside of
react (by the new YT.Player global object). If you are doing new
YT.Player(options) every time you play a video (instead of storing the
player and using loadVideoById for subsequent video loads) then I believe
this will reload the frame and reset the autoplay permissions, causing the
issues you describe.

If I am mistaken and you are in fact using ReactPlayer, hopefully when #13
#13 lands this problem
will be resolved.


Reply to this email directly or view it on GitHub
#12 (comment).

@cookpete
Copy link
Owner

Closing this in light of #13.

@cookpete cookpete closed this Dec 24, 2015
@mgw-sbex mgw-sbex mentioned this pull request Jan 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants