videojs-youtube
videojs-youtube copied to clipboard
Youtube video not playing for iframe-embedded sites (chromium browsers Only - Firefox seems to work)
Hello,
Seems there is a problem when playing Youtube videos in a site which is embedded in another one through an iframe.
After doing some debugging, seems for some reason, the "onPlayerStateChange" is called with state === -1, and is never called again with a different state. I don't know if it's a communication problem with the youtube or what the heck...
Here is a very basic example: https://codepen.io/johnbernardsson/pen/abwdBmR
This won't automatically play in any browser. But, at least in Firefox, if you click on the "play" button, it will start the playblack. In Chromium browsers (tested Edge and Chrome), even playback is not possible. On the other hand, it seems that if the parent site's domain is the same than the iframe-embedded one with the videojs-youtube, this issue is not happening. So I am not sure if that has anything to do with the "origin" param setted in the youtube-iframe-player. I tried to remove it by params, but for some reason seems the youtube API is anyway adding it (so not sure if Youtube guys have some part of guilt here...). This "origin" thing hasn't been tested extensivenly, but mentioning just in case is useful.
At my company we are quite stucked on this. And is a real problem, as we are managing user views, how much the user viewed from a video and other statistics, relying on the video.js API. And of course we provide iframe-embedding of our services, where this problem is coming from.
I added some "dirty hack" to the plugin, which I attach below in case it helps someone, but is not a real fix for the problem. I would be sincerelly thankful if someone with better knowledge could take a look on this...
The infamous hack:
//...
onPlayerStateChange: function(e) {
var state = e.data;
if (state === this.lastState || this.errorNumber) {
return;
}
this.lastState = state;
switch (state) {
case -1:
this.trigger('loadstart');
this.trigger('loadedmetadata');
this.trigger('durationchange');
this.trigger('ratechange');
// == Hack start == //
if (location.search.indexOf('source=embedded') > -1) { //This is how we know in our company the site is being embedded in an iframe
if (this.stateTimeout) {
clearTimeout(this.stateTimeout);
this.stateTimeout = null;
}
this.stateTimeout = setTimeout( () => {
if (this.lastState === -1) {
// Make Video.js UI think we are playing the video, then pause it. For a strange reason, this
// brings up the red "native" Youtube Play button. If you click it, everything will work fine from that point
this.trigger('playing');
this.trigger('play');
this.onSeeked();
this.trigger('pause');
}
}, 1500
)
}
// == Hack end == //
break;
case YT.PlayerState.ENDED:
this.trigger('ended');
break;
case YT.PlayerState.PLAYING:
// == Hack start == //
if (this.stateTimeout) {
clearTimeout(this.stateTimeout);
this.stateTimeout = null;
}
// == Hack end == //
this.trigger('timeupdate');
this.trigger('durationchange');
this.trigger('playing');
this.trigger('play');
// ...
I have the same problem. The thing I've observed, is that if you click fast enough (up to 2-3s after loading) – the video will play in a matter of fact.
Did you ever find a long term solution here? I came across this after noticing I could embed a video directly using YouTube, play it, then bounce back to the VideoJS player and it would play (which is what your solution is replicating). We also have the same issue with Kaltura player using YouTube content. By any chance are you on a managed Chrome browser (I can only replicate it on our institution's managed instance, but have one user that states theirs is not managed)?
Interesting. Try setting:
player.muted(true);
For myself, the videos now play correctly. Found lower in the comments in this stackoverflow thread: https://stackoverflow.com/questions/54944500/problems-with-youtube-iframe-api-to-start-playing-video-on-chrome
Last message, and I hope it's useful to those experiencing the above. On the site you're having issues with, make sure Sound is toggled to on (the dropdown under the lock/secure icon in the url bar). If it's not an option, choose site settings and set Sound to allow (not automatic). This appears to be intended Chrome behavior, but it definitely threw me through a loop to find.
set muted option, it works!
For any others out there having this problem, we found that with our site, we needed to add the next level down domain into the allow="autoplay" specification like:
allow="autoplay 'self' https://subdomain.childsite.com"
Everything started working without having to mess with muted any longer.