1

I'm having problems enqueuing a playlist using the YouTube IFrame API. (https://developers.google.com/youtube/iframe_api_reference#Queueing_Functions)

I'm using flash to show the youtube videos. Using HTML5 shows another issue where the videoplayback call is called multiple times before the video loads.

On loading the playlist, the video itself doesn't load. It shows up in the network tab as a call to videoplayback that is 'pending' until it times out after 7.5 minutes at which point it tries again and everything works. The playlist, incidentally, has loaded successfully - mousing over the youtube iframe shows a loaded playlist.

The code to replicate this is below, and the issue is found following these steps: 1. Click a channel 2. If channel loads, goto 1, else check network tab.

I know the method of replication is contrived, however I'm seeing this 'sometimes' on first load.

The playing channel isn't at fault - this has been seen with many different channels.

Is it my code? Is there a work around? Is there a fix?

Tested on Windows 7 32bit using Chrome 28, Firefox 22.0 and IE 10

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
        <title>
            Youtube Test
        </title>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
        <script type='text/javascript'>
var collection = [];
var player = null;
var playlistEnqueued = false;

function clear() {
    // Removes the iframe.
    if (player !== null) {
        player.destroy();
    }

    collection = [];
    playlistEnqueued = false;
    player = null;
}

function createYT(videoId) {
    // Clear anything that's up currently
    clear();

    // Yes, this could be $.ajax, however this way reduces the dependency on jQuery
    // further for the purposes of this test.
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            parseJSONResponse(JSON.parse(xmlhttp.responseText));
        }
    }
    xmlhttp.open("GET", "https://gdata.youtube.com/feeds/users/" + videoId + "/uploads?alt=json", true);
    xmlhttp.send();
}

function parseJSONResponse(data) {
    var feed = data.feed;
    $.each(feed.entry, function(index, entry, list) {
        collection.push(entry.id.$t.match('[^/]*$')[0]);
    });
    playVideo();
}

function playVideo(videoId) {
    try {
        if (videoId === undefined || videoId === null) {
            videoId = collection[0];
        }
        if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
            window.onYouTubeIframeAPIReady = function() {
                playVideo(videoId);
            };
            $.getScript('//www.youtube.com/iframe_api');
        } else {
            if (playlistEnqueued === true) {
                player.playVideoAt(0);
            } else {
                player = new YT.Player('video', {
                    events: {
                        'onReady':function(event) {
                            try {
                                player.cuePlaylist(collection);
                            } catch (e) {
                                console.error(e);
                            }
                        },
                        'onError':function(error) {
                            console.error(error);
                        }
                    },
                    videoId: videoId,
                    width: 425,
                    height: 356,
                    playerVars: {
                        autoplay: 1,
                    }
                });

                // Attaching event listener after object creation due to
                // http://stackoverflow.com/questions/17078094/youtube-iframe-player-api-onstatechange-not-firing
                player.addEventListener('onStateChange', function(state) {
                    try {
                        stateChanged(state);
                    } catch (e) {
                        console.error(e);
                    }
                });
            }
        }
    } catch (e) {
        console.error(e);
    }
}

function stateChanged(state) {
    // This state will be called on enqueueing a playlist
    if (state.data == 5) {
        playlistEnqueued = true;

        playVideo();
    }
}

$(document).on('ready', function() {
    var player = $(document).find("#player");

    $("a").on('click', function() {
        var channel = $(this).attr('data-channel');
        createYT(channel);
        return false;
    });
});

        </script>
    </head>
    <body>
        <div class='test'>
            <div id='video'>
            </div>
            <a href='#' data-channel='mit'>MIT</a>
            <a href='#' data-channel='tedtalksdirector'>TED</a>
            <a href='#' data-channel='minutephysics'>Minute Physics</a>
        </div>
    </body>
</html>

When using flash, and on waiting for the video connection to timeout and try again the following is seen in the network tab. As you can see it's 'pending', failed, and then tried again after 7.5 minutes.

Chrome network tab once the video starts playing: Chrome network tab on video playback

More images when I get past 10 reputation...

1 Answers1

0

I've got this up and running on jsFiddle (http://jsfiddle.net/3Bm2V/5/) and it seems to be working ok. I did have to change the

$(document).on('ready', function () {

to

$(function() {

to get it to work in jsFiddle, so try the link above and see if it works for you now?

TFk
  • 51
  • 4
  • Sadly no. I can't put images onto SO yet so I can't show you what the network tab of Chrome looks like, however even within your JS Fiddle I've managed to replicate the issue I described. – Dominic Orme Jul 18 '13 at 16:11
  • Your script seems to be working. I added: at the top of the page and at the start of . – Als Jul 19 '13 at 08:59
  • In Chrome i get these errors after clicking the link TED, but the first video is loaded and starts to play automatically. Errors in console are: Blocked a frame with origin "http://www.youtube.com" from accessing a frame with origin "http://localhost". Protocols, domains, and ports must match. www-embed-player-vflT5t3ca.js:217 g.Ua www-embed-player-vflT5t3ca.js:217 g.vd www-embed-player-vflT5t3ca.js:216 g.qb www-embed-player-vflT5t3ca.js:215 (anonymous function) www-embed-player-vflT5t3ca.js:209 Uncaught TypeError: Cannot call method 'apply' of undefined www-widgetapi-vfluS_Dp5.js:22 – Als Jul 19 '13 at 09:10
  • There appears to be multiple _possible_ issues happening. I'm using flash to show the YouTube videos, and get the issue detailed in the original post. However, on using the HTML5 viewer there is another issue cropping up where the videoplayback call is made multiple times, and eventually works. – Dominic Orme Jul 19 '13 at 09:42
  • @Als - what do you see in your network tab, rather than console? The bug can be seen within the jsFiddle too. – Dominic Orme Jul 19 '13 at 09:56
  • I see you added the 2 lines i mentioned. – Als Jul 19 '13 at 12:41
  • The jsFiddle plays the loaded video automatically after clicking a link. Using your script: In the network tab i see hundreds of GET requests. I also get the same error at the bottom of the network tab: Blocked a frame with origin "http://www.youtube.com" from accessing a frame with origin "http://localhost". Protocols, domains, and ports must match. www-embed-player-vflT5t3ca.js:217 g.Ua www-embed-player-vflT5t3ca.js:217 g.vd www-embed-player-vflT5t3ca.js:216 g.qb www-embed-player-vflT5t3ca.js:215 (anonymous function) www-embed-player-vflT5t3ca.js:209 – Als Jul 19 '13 at 12:49
  • I see no pending request and after clicking a link a video starts to play within 10 seconds. – Als Jul 19 '13 at 12:57
  • @Als - Updated the issue again. I've added an image of my network tab. Are you using the HTML5 player? Right click the video if you don't know. – Dominic Orme Jul 19 '13 at 13:47
  • I don't see the error that is shown in your image. I have no pending request on my Chrome network tab. With Chrome the flash player (version 11,8,800,97) is selected. With Firefox the html5 player is selected. Both are working fine. – Als Jul 19 '13 at 14:36