2
votes

I'm really having a frustrating time handling YouTube's iFrame API. Everything was working fine until yesterday, when I noticed my .playVideo() and .pauseVideo() functions throw an "undefined is not a function" error. Now, I can see that none of my functions appear to work... the events "onready" and "onstatechange" don't appear to be firing either. Here's my code:

function addVideo(index, url){
                $.getScript('https://www.youtube.com/iframe_api', function(){
                    processPlayer();
                });
                function processPlayer(){

                    var videos = document.getElementById("videos");
                    var individ = document.createElement("div");
                    individ.setAttribute("class", "individ");
                    var vid = document.createElement("div");
                    vid.setAttribute("id","vid"+index);
                    individ.appendChild(vid);
                    videos.appendChild(individ);
                    var player;
                    function onYouTubeIframeAPIReady() {
                        console.log("Are we here at least?");
                        player = new YT.Player('vid'+index, {
                            height: '165',
                            width: '100%',  
                            videoId: url,
                            playerVars: { 'controls': 0, 'showinfo': 0, 'rel': 0},
                            events: {
                                'onReady': onPlayerReady,
                                'onStateChange': onPlayerStateChange
                            }
                        });
                        window.players.push(player);

                        //individ.innerHTML+="Added by "+namesList[index];
                        individ.innerHTML+="<div style='float: left;'><span class='sname'>Let it Burn</span><br/><span class='aname'>Dave Matthews Band</span></div><div style='position: relative;'><img class='s_user' src='http://i.imgur.com/1AmnCp4.png'/></div>";
                        window.players.push(player);
                    }

                    onYouTubeIframeAPIReady();

                    // 4. The API will call this function when the video player is ready.
                    function onPlayerReady(event) {
                        //event.target.playVideo();
                        console.log("We're ready");
                    }

                    // 5. The API calls this function when the player's state changes.
                    //    The function indicates that when playing a video (state=1),
                    //    the player should play for six seconds and then stop.
                    var done = false;
                    function onPlayerStateChange(event) {
                        console.log("HI?");
                        if(event.data === 0) {  
                            if(window.currentIndex < window.players.length-1){
                                var videoID = window.players[window.currentIndex].getVideoUrl().split("v=")[1];
                                window.players[window.currentIndex].cueVideoById(videoID);
                                window.currentIndex++;       
                                window.players[window.currentIndex].playVideo();
                            } 
                        } else if(event.data === 2 ){
                            onYouTubeIframeAPIReady();
                        }
                        if(!window.playing){
                            //alert('playing');
                            window.playing = true;
                        } else {
                            //alert('stopping');
                            window.playing = false;
                        }
                    }
                    function stopVideo() {
                        player.stopVideo();
                    }
                }
            }

Any ideas why? I'd really appreciate some help on this. The video itself loads fine, and the YTPlayer object can be called from console... yet these functions don't work, and onready/onstatechange don't fire. The iframes by default have the "origin=" bit in there, so that fix didn't work either.

1

1 Answers

1
votes

I see several problems in your code, but I'm not sure which one of them is the one that's bothering you.

First of all, you're not supposed to call onYouTubeIframeAPIReady directly.

Instead, you should execute the following and let the browser do it asynchronously:

var scriptElement = document.createElement("script");
scriptElement.src = "http://www.youtube.com/iframe_api";
var firstScriptElement = document.getElementsByTagName("script")[0];
firstScriptElement.parentNode.insertBefore(scriptElement,firstScriptElement);

Second, I believe that you should initialize at least the following player parameters:

playerVars:
{
    "enablejsapi":1,
    "origin":document.domain,
    "rel":0
},
events:
{
    "onReady":onPlayerReady,
    "onError":onPlayerError,
    "onStateChange":onPlayerStateChange
}

Here is the complete relevant piece of code that I have been using:

<body onload="LoadYouTubeIframeAPI()">
    <div id="player">Loading Video Player...</div>
    <script type="text/javascript">
        var player = null;
        function LoadYouTubeIframeAPI()
        {
            var scriptElement = document.createElement("script");
            scriptElement.src = "http://www.youtube.com/iframe_api";
            var firstScriptElement = document.getElementsByTagName("script")[0];
            firstScriptElement.parentNode.insertBefore(scriptElement,firstScriptElement);
        }
        function onYouTubeIframeAPIReady()
        {
            var playerParams =
            {
                playerVars:
                {
                    "enablejsapi":1,
                    "origin":document.domain,
                    "rel":0
                },
                events:
                {
                    "onReady":onPlayerReady,
                    "onError":onPlayerError,
                    "onStateChange":onPlayerStateChange
                }
            };
            player = new YT.Player("player",playerParams);
        }
        function onPlayerReady(event)
        {
            ...
        }
        function onPlayerError(event)
        {
            ...
        }
        function onPlayerStateChange(event)
        {
            ...
        }
    </script>
</body>