Youtube iFrame (with javascript API) loads the first time, but not the second. What for?

I am using the iFrame Youtube API with the following code. I call this view using Ajax to render it and add it to the div.yt player on my page. It works the first time I call a view, but after I close the video (it empties the div.yt player) and click on another link that calls my opinion, the video does not load at all (empty). I struggled and still do not understand why this is happening, especially that it works for the first time. Any help would be greatly appreciated. Thanks.

PS: Both html and javascript are rendered in 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(); } 
+4
source share
2 answers

Just check if the script is 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(); }; 
+6
source

I debugged the problem. onYouTubeIframeAPIReady () is only called the first time the YouTube API is loaded (when the user refreshes the page and clicks the link to the view, for example), and because I call my views in Ajax, this did not work at the following times.

So, I replaced the first block of code by wrapping it in a conditional expression:

  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 youtube_api_init for the browser to remember that the YouTube API is already loaded:

 var youtube_api_init = 1; 

PS: the first time I tried, I named my variable yt_api_init instead of youtube_api_init, and it didn’t work because it happens that the name YouTube already uses in its api ...

+1
source

All Articles