I am using the iFrame Youtube API with the following code. I call this view with Ajax to render it and append it in a div.yt-player within my page. It works the first time I call the view, but after I close the video (it empties the div.yt-player) and click on another link that calls my view, the video doesn't load at all (blank). I've been struggling and still don't see why it happens, especially that it works the first time. Any kind of help would be much appreciated.. Thanks.
PS: Both the html and the javascript are rendered by the view.
Html
<div id="player"></div>
Javascript:
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '486',
width: '864',
videoId: '#{@media['youtube_url']}',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
},
playerVars: {
'showinfo': 0,
'iv_load_policy': 3,
'color': 'white',
'fs': 1,
'autoplay': 1,
'vq': 'hd720'
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
Just check if the script has been defined.
if(document.getElementById('iframe_api') === null){
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
tag.id = "iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
else
runPlayer();
function runPlayer(){
var player;
player = new YT.Player(element.children()[0], {
playerVars: {
autoplay: 1,
html5: 1,
controls: 1,
showsearch: 0,
showinfo: 0
},
height: scope.height,
width: scope.width,
videoId: scope.videoid,
events: {
onStateChange: function (event) {
if (event.data == YT.PlayerState.ENDED) {
scope.$emit('VideoEnded');
}
}
}
});
}
$window.onYouTubeIframeAPIReady = function () {
runPlayer();
};
I debugged the problem. onYouTubeIframeAPIReady() is called only the first time the YouTube API is loaded (when the user refreshes the page and clicks on the link to the view for example), and because I'm calling my views in Ajax, it didn't get fired up the following times.
So I replaced the first block of code by wrapping it in a conditional:
if (typeof youtube_api_init == 'undefined') {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
and
if (typeof youtube_api_init != 'undefined') {
onYouTubeIframeAPIReady();
}
and at the end of the script, I set the youtube_api_init for the browser to remember the YouTube API has already been loaded:
var youtube_api_init = 1;
PS: the first time I tried, I called my variable yt_api_init instead of youtube_api_init, and it didn't work cause it happens that's a name YouTube already uses in its api...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With