YouTube API OnStateChange Listener Stops Working A

2019-02-11 08:42发布

问题:

I am trying to change the video playing in the YouTube iframe in the cleanest way possible and a few months ago I had this code working, but YouTube changed their API and it stopped working for me. Now the onPlayerStateChange event is not firing after I switch out the video's SRC attribute to switch the video that is playing. I'm an amateur to coding so I may be missing something simple here, but any input would be greatly appreciated. Below is a code that loads a YouTube video and when it ends, there's an alert that automatically pops up for you. However, when you click the button and switch the video by switching out the SRC attribute, the alert function stops working and its as if the entire onPlayerStateChange function stops working. I could not get it working in jsfiddle, but a link to a live demo can be found at http://thetunedrop.com/test.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div id="player"></div>
<button class="button" data-youtubeid="b-3BI9AspYc">BUTTON</button>
</body>
</html>
<script type="text/javascript" src="jquery/jquery.min.js"></script>
<script type="text/javascript" src="jquery/js/jquery-ui-1.8.22.custom.min.js"></script>
<script src="http://www.youtube.com/player_api"></script>
<script>
// create youtube player
var player;
function onYouTubePlayerAPIReady() {
    player = new YT.Player('player', {
      height: '390',
      width: '640',
      videoId: '0Bmhjf0rKe8',
      events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
      }
    });
}

// autoplay video
function onPlayerReady(event) {
    event.target.playVideo();
}

// when video ends
function onPlayerStateChange(event) {        
    if(event.data === 0) {            
        alert('done');
    }
}

function load_ytid(youtubeid){
$("#player").attr("src", "http://www.youtube.com/embed/" + youtubeid + "?fs=1&autoplay=1");
}
$(document).ready(function(){

$(".button").on("click", function(){
var youtubeid = $(this).data("youtubeid");
load_ytid(youtubeid);   
});

});
</script>

回答1:

Try this instead :

<!DOCTYPE html>
<html>
<body>
    <script src="jquery-1.10.2.min.js"></script>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>
    <button class="button" data-youtubeid="b-3BI9AspYc">BUTTON</button>

    <script>
        // 2. This code loads the IFrame Player API code asynchronously.
        var tag = document.createElement('script');

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

        // 3. This function creates an <iframe> (and YouTube player)
        //    after the API code downloads.
        var player;
        function onYouTubeIframeAPIReady() {
            player = new YT.Player('player', {
            height: '390',
            width: '640',
            videoId: '0Bmhjf0rKe8',
            playerVars: { 'autoplay': 1, 'controls': 1 },
            events: {
                'onReady': onPlayerReady,
                'onStateChange': onPlayerStateChange
            }
            });
        }

        var playerReady = false;
        // 4. The API will call this function when the video player is ready.
        function onPlayerReady(event) {
            playerReady = true;
        }


        // 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.
        function onPlayerStateChange(event) {
            if (event.data == YT.PlayerState.ENDED ) {            
            alert('done');
            }
        }

        $(".button").on("click", function(){ 
            player.loadVideoById("Vw4KVoEVcr0", 0, "default"); 
        });

    </script>
</body>
</html>

The fiddle here : http://jsfiddle.net/QtBlueWaffle/8bpQ8/1/

Hope this helps



回答2:

I had kind of the same problem (I Think)... I wanted the user to be able to change the content for multiple players, and this is what works for me: I call the youtube api with a onload function additional to the new Youtubelink, so that reloads every time the iframe changes.

MY HTML:

<iframe onload="floaded1()" id="player1" width="240" height="220" 
src="http://www.youtube.com/embed/0Bmhjf0rKe8
?enablejsapi=1&rel=0&showinfo=2&iv_load_policy=3&modestbranding=1" 
frameborder="0" allowfullscreen> </iframe>

MY JS:

function floaded1() {

player1 = new YT.Player('player1', {
        events: {
            'onStateChange': function (event) {
if (event.data == 0) {
alert('done');
};
            }
        }
    });
}

WHAT I LOAD WITH A VIDEO PICKER:

html += '<iframe onload="floaded1()" id="player1" width="240" height="220"
src="http://www.youtube.com/embed/'+YouTubeVideoId+'?enablejsapi=1&rel=0&
showinfo=2&iv_load_policy=3&modestbranding=1" frameborder="0" allowfullscreen> 
</iframe>';