I'm using videojs-youtube plugin to play embedded youtube videos inside my web-app. Recently I have noticed that when the web-app is being wrapped inside an iframe, the video gets stuck on infinite loading. The console doesn't show any related errors due this process.
While trying to debug this problem I realised that the PlayerStatus (as described in IFrame Player API) is being changed in a wrong way:
When the video isn't wrapped in iframe the PlayerStatus changes from 'unstarted' to 'buffering' and to 'playing'. On the other hand, When the video is being wrapped in iframe the PlayerStatus changes from 'unstarted' to 'buffering' to 'unstarted' once again.
And there is one weird exception though - when chrome extensions such as AdBlock or LastPass are installed and activate, the video plays properly, even if its inside an iframe.
Any idea why is this happening?
Thanks :)
I had the same issue but I think I've found a solution for my problem after hours of trying... Adding allow="autoplay" to the iframe fixes it for me, it doesn't make total sense since sometimes it does work without adding this.
To clarify, I'm using video.js and videojs-youtube.js in an iframe, inside that iframe, if you play a Youtube video, another iframe is created inside the iframe. And I'm guessing that clicking on the video player to play Youtube video isn't considered user interacting with the inner iframe, because videojs-youtube programmatically tells youtube video to play in that inner iframe, and Chrome doesn't allow video inside an iframe to be played unless user has interacted with it.
This doesn't explain why 5 percent of the time it does play fine. Anyways, adding allow=autoplay to the outer iframe tag that contains the videojs player makes it work 100 percent of the time for me.
Related
I've spent way too many hours on this with very little success. We have a client with a site that has a YouTube video popup when the page loads. It autoplays on desktop and shows the Youtube play button on mobile since autoplay is not supported on mobile. I am using the iFrame JS API to instantiate the video player (code examples below). This setup is working perfectly on desktop, but on mobile devices (Android or iOS), between myself and my coworkers, clicking the Youtube play button only plays the video about 80% of the time. The rest of the time the video loading spinner just spins and nothing happens. If I close a reload the player using the site controls it will play, but not initially.
I know that this will not be an issue for the majority of users viewing the site but I know our client is going to go ape crazy if, out of 100 reloads on their iPhones, even 10 of them result in this behavior.
I am instantiating the player as follows:
1) I am including a "hard copy" of the Youtube iframe api JS on the site first.
2) I have an object controlling the display of the youtube "modal" window that contains the player target -- when the function is called it does the following:
// Write a div element to the container
_instance.videoContainer.innerHTML = '<div id="youtube-player"></div>';
// Grab a reference to it
_instance.el = document.getElementById('youtube-player');
// Call the YT player API
_instance.player = new YT.Player('youtube-player', {
playerVars: { // trying a bunch of different params with no success
playsinline : 1 ,
origin : window.location.origin ,
autoplay : 1 ,
wmode: "opaque" ,
iv_load_policy : 3
},
videoId: videoId , // This is passed to the function
events : {
onReady : function(){
console.log('resolved player');
// another function that just changes the container visibility
_instance.play();
},
onStateChange : function( event ){
if( event.data == YT.PlayerState.ENDED ){
_instance.close();
}
}
}
});
At this point, the video is either playing automatically in desktop 100% of the time, or it has shown the Youtube player with the video thumbnail and big red play button on mobile. This is where the trouble starts -- most of the time it plays fine, the rest of the time it just spins and spins and never plays. What's interesting is, on Android, if I blur the window and reopen it, I can click the play button again and it will play.
It shouldn't matter at this point, but I am destroying the div and the player reference when the modal is closed.
I've tried pretty much everything I can think of...
The Youtube video is somehow being throttled and only showing so many times through the iframe to the origin? I added the 'origin' property to the params thinking this might be the case, but it didn't seem to make much of a difference. I seem to have a higher success rate than my coworkers loading the video.
Is there some reason to asynchronously load the youtube iframe script as in the examples, rather than loading a copy from my site?
That's all I can think of at this point... is there something I'm missing? Thanks.
There is a related thread which stated that the autoplay function is not allowed for most mobile devices.
From this documentation:
Due to this restriction, functions and parameters such as autoplay, playVideo(), loadVideoById() won't work in all mobile environments.
A simple workaround is to have a custom looks of the "play" button:
Have an overlay element with pointer-events: none;. pointer-events works on all modern mobile browsers or simply have the video container over the button with opacity: 0.
Hope this helps!
I ran into the almost the same exact problem. For us it was specific to cellular connections.
If the embed is larger than ~360px wide, the player attempts to serve up quality at "large" or higher to which AT&T and Verizon are throttling.
The result we see: player enters buffering state and cannot achieve playback.
Tests over T-Mobile work OK without issue.
Players embedded at or below 360px wide play OK on all networks at quality of "medium" or lower.
I refer to the demo code for the YouTube iframe demo located at: https://developers.google.com/youtube/youtube_player_demo. This works perfectly on my desktop and my iPhone, but it will not do so on my iPad in the Safari browser. I obtain a black screen instead. I have modified the code to prevent it auto starting (I have a button now for that). I also write event.target.getPlayerState() to a div on the screen so that I can see what is going on. I wish to use to use the iFrame player and to control it using Javascript.
When it starts up I obtain the still frame from the video (as expected) and the red play button. The getPlayerState() is 5 at this time (video cued). As soon as I hit play the player iframe goes black and the getPlayerState() changes to 3 (buffering). That is it, it will just sit there for hours without change.
I get the same black screen when I try the demo located at: https://developers.google.com/youtube/youtube_player_demo.
I have no difficulty playing a video the YouTube website. Also if I go to any video on the Youtube site and get the iframe embed link then I have no difficulty playing this from a web page. This of course does not have a a Javascript interface.
Has anyone any suggestions? What other info should I provide.
Many thanks.
Peter
This has since fixed itself. But now the demo code will not work on Internet Explorer, the on ready is not firing. There are many posts regarding this on Stackoverflow, but all marked closed. I will investigate further and if necessary open a new post.
I am embedding a youtube/vimeo video onto my site with an iframe.
<iframe src="http://www.youtube.com/embed/{$entity->getYoutubeVideoID()}" ...></iframe>
The {$entity->getYouTubeVideoID()} bit is smarty template code syntax. I don't think that is the problem because the video uploads and plays fine in Chrome and IE9 and up. The video also uploads to firefox and safari fine, meaning I can see the video and it's the right one. But when I click the video it does not play in either firefox or safari.
What is interesting is that the other events are triggered. That is, on mouseover the play buttons on the videos change. On the youtube videos, the button in the middle with the play icon starts out as grey and on mouseover turns to red. So the iframe is registering events. But, it won't play on click. I have no idea where to go from here.
The only other event handlers I have on the iframe is this one but I doubt that is messing it up:
$(window).blur(function(){
if($('iframe').is(':focus')){
mySwipe.slide(mySwipe.getPos(), 1000);
}
});
(mySwipe refers to the swipe.js slideshow library)
I had an issue with playback buttons in firefox also. I was using a html5 Doctype, so I added the following after the youtube url
&html5=1
maybe this might help you.
I simply could not get embedded videos to play inside the swipe.js library (or any other touch enabled jquery library). My solution was to extract thumbnail images from vimeo/youtube APIs and use them as placeholders in the slideshow. Then register a click event on the thumbnail that opened the video in a lightbox.
I know this thread is six years old, but I recently had this problem and all of the solutions on the internet did not work. But I figured it out for my site:
If you have a secure site (HTTPS) and you embed a youtube video with the code posted here,
iframe src="http://www.youtube.com/embed/{$entity->getYoutubeVideoID()}" ...
... Firefox will block it, because that is "Mixed content." HTTP is unsecure, so it is not allowed to show.
Youtube is an HTTPS site, so including that "s" in your URL will allow it to play in Firefox and IE without having to disable security.
Flexslider 2 basically solved it. Swipe.js is wonderful, but with playing youtube/vimeo in a slider Flexslider works better.
I have more than 15 thumbnail images displayed(fetched from DB and looped) on the webpage. Onclick of an image, I have an overlay which plays the youtube video(iframe version).
The problem is that, on closing the overlay, the youtube video continues to play.
After going through the YT documentation, I figured out that there is no way to control the YTplayer inside an iframe. But, I have to use an iframe because embed and object tags make use of flash and flash is not supported in Mac(Mountain Lion)
So, I was thinking, if there is a way to deactivate iframe then the player may stop. display:none; does not help.
Please suggest.
Thanks in advance.
I tried this method and it works:
I fetch the iframe source by id using javascript and make the source blank.
<script>
function stopVideo(){
document.getElementById("iframeID").src= "";
}
</script>
I am using JavaScript to wrap an HTML5 video player in a div for styling purposes. If the mark-up exists when the page loads, the player functions as it should. However if I apply the wrapper dynamically with JavaScript, the player goes black and its controls are inaccessible. I have tested applying various elements as wrappers, and it seems to happen with any block level element, but not inline elements. I can't find any documentation on this bug or others who have encountered it via Google. Anyone have a workaround?
I see this was posted a long time ago & I ran into a similar issue.
When a video is reparented (like it would be if you used a solution like slick, it reverts to 00:00 and pauses. Once reparented, you should be able to directly access the video via JS & invoke the play() method to get it started again.