1
votes

i'm working on a webpage. I'm using jQuery load (AJAX) function to dynamically load new content into the content div. In each of these content divs there is an image. When you click on that image a Youtube embedded video (iframe) should start playing. Everything works so far, but there is one thing, which is kind of strange:

Whenever i start playing a Youtube Video the buffering starts. If i now want to load a new content into the content div while buffering the jQuery load function gets fired after the buffering has finished. So sometimes i'll have to wait like 10 seconds before the content changes (simple HTML content), because the video is buffering. If i'm not using the iframe embed, but the object embed everything works, but i want to support mobile devices as well (iOS). So just a simple example to show you:

$(".content").load(NEW_CONTENT_URL, function() {
    // Some animation to replace the oldcontent with the new one

    // If a iframe embeded video is buffering, this function doesnt get fired. Only after the buffering has finised.
});

Is it a known bug in jQuery AJAX load or Youtube iframe embed. Is there anything i can do about it or do i have to use the object (swf) embed code to make it work. If yes, could you please tell me, how to use the Youtube API for object embeds. I can't get "playVideo()" to work on an existing object. Everytime i'm getting an error: TypeError: 'undefined' is not a function (evaluating 'playerArr["player"].playVideo()');

But that is strange as well, because i'm using this function for the embedded swfs

var playerArr = [];
function onYouTubePlayerReady(playerId) {
      alert(playerId);
      playerArr[playerId] = document.getElementById(playerId);
      playerArr[playerId].playVideo();

}

And yes, i also used "?enablejsapi=1" for the Video URL. The alert gives me a "player", which is the id for my object. The iframe solution would be better though.

Thanks in advance for your help.

1

1 Answers

1
votes

I think it's not very easy understandable from the google Api doc but to get iframe properly running on my site I had to be carefull about the 3 following points :

1/ Get the Iframe specific API loaded : https://www.youtube.com/iframe_api

var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

2/ Declare the correct callback wich name is different by API : onYouTubeIframeAPIReady

 var player;
 function onYouTubeIframeAPIReady(){
 player = new YT.Player('player', {
    height: '390',
    width: '640',
    videoId: 'M7lc1UVf-VE',
    playerVars: {'autoplay':'0','rel':'0','control':'0','fs':'1'},
    events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
        }
    });
}

3/ and finnaly be sure to never use this parameter : enablejsapi : 1

full sample from our jQuery pluggin (ugly but functionnal) :

$(data.settings.contentData).each(function (index, currentData) {
     var html = '<li style="position:relative;float: left">';
     html += '<div id="player"></div>'
     html += "<script type='text/javascript'>"
     html += "var player; "
     html += "var tag = document.createElement('script');"
     html += "tag.src = 'https://www.youtube.com/iframe_api';"
     html += "var firstScriptTag = document.getElementsByTagName('script')[0];"
     html += "firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);"

     html += "function onYouTubeIframeAPIReady() { "
     html += "   player = new YT.Player('player', "
     html += "       {height: '390', width: '640',  videoId: '" + $.trim(currentData.images.zoom) + "', "
     html += "       playerVars: {'autoplay':'0','rel':'0','control':'0','fs':'1'}, "
     html += "       events: {'onReady': onPlayerReady}}"
     html += "   ); "
     html += "}; "
     html += "function onPlayerReady(event) { /* your stuff here */ }</script>";
     html += '</li>';
    containerListImage.append(html);
    var containerImage = containerListImage.children().last();
  ...
}