I've been battling with the youtube iframe api for quite some time now. Somehow the method onYouTubeIframeAPIReady
is not always triggered.
From the symptoms it seems a loading problem. No errors are shown in the inspector.
Here is my code:
HTML
<div id="player"></div>
<script>
videoId = 'someVideoId';
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
</script>
JS
(called at the end of the page. I tried to place the code right after the above script and the result was the same.)
var isReady = false
, player
, poster
, video;
$(function () {
$('.js-play').click(function (e) {
e.preventDefault();
interval = setInterval(videoLoaded, 100);
});
});
function onYouTubeIframeAPIReady() {
console.log(videoId)
player = new YT.Player('player', {
height: '445',
width: '810',
videoId: videoId,
events: {
'onReady': onPlayerReady//,
//'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
isReady = true;
console.log("youtube says play")
}
function videoLoaded (){
if (isReady) {
console.log("ready and play")
poster.hide();
video.show();
$('body').trigger('fluidvideos');
player.playVideo();
clearInterval(interval);
}
}
The problem is that sometimes nothing gets printed by the console.log
and nothing happens.
On mobile phones this happens all the time. Any ideas?
If you have to put in inside to a function, one possible solution is instead of:
you can declare it like this:
In this case make sure, that you insert the certain script to the dom after the declaration (the
insertBefore()
call what is in the global scope now in your case):After revisiting this, I found a working solution for me when using webpack (or I assume any other commongJS module system), or if you find the youtube api is ready before your own JS file, was to use an interval - until youtube provides some form of promise callback:
This seemed to be the most error-proof in my case.
I was able to make this work under almost all circumstances with a simple setTimeout on load of the page. Not ideal, I know, but it is just another check that fixes the problem most of the time.