0

I need multiple youtube player inside each .player div, But here only one player is loading with my code. So can anyone please help me to find where is the problem?

$(document).ready(function(){
var iframeCount = $('.player');
iframeCount.each(function (index) {
    $(this).attr('id', 'player-'+index);
});

var player, pId, playerText; 
$('.start-video').on('click', function (index) {     
    onPlayerStateChange = function (event) {
        if (event.data == YT.PlayerState.ENDED) {
        event.target.destroy();
        }
    }   
    playerText = $(this).siblings('.player').text();
    pId = $(this).siblings('.player').attr('id');        
    
    var tag = document.createElement('script');
    tag.src = "https://www.youtube.com/iframe_api";
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    
    onYouTubeIframeAPIReady = function () {
        player = new YT.Player(pId, {
           height: '244',
           width: '434',
           videoId: playerText,  // youtube video id
           playerVars: {
              'autoplay': 1,
              'rel': 0,
              'showinfo': 0
           },
           events: {
              'onStateChange': onPlayerStateChange
           }
        });
    }
    $(this).parent().find('.start-video').fadeOut();
});   
});
.y-video{
      position: relative;
      display: inline-block;
      min-width: 434px;
      min-height: 262px;      
  }
  .y-video img{
    position: absolute;
    width: 434px;
    height: 244px;
    left: 0;
    top: 0;
  }  
  .play-icon{
        display: inline-block;        
        position: absolute;
        left: 0;
        right: 0;
        margin: 0 auto;
        top: 42%;
        z-index: 1;
        width: 40px;
        font-size: 26px;
        border: 3px solid #fff;
        border-radius: 50%;
        text-align: center;
        color: #fff;
        padding: 4px 0 4px 5px;
        cursor: pointer;
        background: rgba(0,0,0,.7);
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="y-video">
    <div class="player">gpzuVt_mkKs</div>    
    <span class="play-icon start-video">&#9655;</span>
    <img class="start-video" src="http://img.youtube.com/vi/gpzuVt_mkKs/0.jpg">
  </div>
  
  <div class="y-video">
    <div class="player">Ep6U7vGjFw0</div>    
    <span class="play-icon start-video">&#9655;</span>
    <img class="start-video" src="http://img.youtube.com/vi/Ep6U7vGjFw0/0.jpg">
  </div>
  
  <div class="y-video">
    <div class="player">6lt2JfJdGSY</div>
    <span class="play-icon start-video">&#9655;</span>
    <img class="start-video" src="http://img.youtube.com/vi/6lt2JfJdGSY/0.jpg">
  </div>
kravisingh
  • 1,640
  • 12
  • 16
  • You are aware the you are creating multiple script tags due to appending them within your `.each()` loop `$('.y-video').each(function (index) `. Also, why not just have one player to play the videos? You could set the position of the video depending on which `img` is clicked... – NewToJS Aug 04 '17 at 08:57
  • @NewToJS Thanks !!! Now edited my code to remove each function and now loading the player on image click, but still it's load only one video who clicked first. – kravisingh Aug 04 '17 at 12:45

2 Answers2

0

You need to separate the classes of each player (e.g. player1, player2 onwards), this will help your application separate each code/player.

Code snippet from a related SO post:

<div id="ytplayer1"></div>
<div id="ytplayer2"></div>

<script>
  var player;
  var player2;
  function onYouTubePlayerAPIReady() {
    player = new YT.Player('ytplayer1', {
      height: '390',
      width: '640',
      videoId: 'hdy78ehsjdi'
    });
    player2 = new YT.Player('ytplayer2', {
      height: '390',
      width: '640',
      videoId: '81hdjskilct'
    });
  }
</script>

There is also a Github code for playing multiple videos using Youtube API iFrame.

Hope this helps.

Mr.Rebot
  • 6,703
  • 2
  • 16
  • 91
  • 1
    Thanks, but there will be n number of players on the each page, so I can't separate the classes of each player (e.g. player1, player2 onwards). Another side I will try Github code and let you know if it will work for me. – kravisingh Aug 04 '17 at 18:44
0

Used following reference to fix my issue: [http://jsfiddle.net/KtbYR/5/][1]

$(document).ready(function(){
var iframeCount = $('iframe');
    iframeCount.each(function (index) {
        $(this).attr('id', 'player-'+index);
    });
});
    
function getFrameID(id) {
    var elem = document.getElementById(id);
    if (elem) {
        if (/^iframe$/i.test(elem.tagName)) return id; //Frame, OK
        // else: Look for frame
        var elems = elem.getElementsByTagName("iframe");
        if (!elems.length) return null; //No iframe found, FAILURE
        for (var i = 0; i < elems.length; i++) {
            if (/^https?:\/\/(?:www\.)?youtube(?:-nocookie)?\.com(\/|$)/i.test(elems[i].src)) break;
        }
        elem = elems[i]; //The only, or the best iFrame
        if (elem.id) return elem.id; //Existing ID, return it
        // else: Create a new ID
        do { //Keep postfixing `-frame` until the ID is unique
            id += "-frame";
        } while (document.getElementById(id));
        elem.id = id;
        return id;
    }
    // If no element, return null.
    return null;
}

// Define YT_ready function.
var YT_ready = (function() {
    var onReady_funcs = [],
        api_isReady = false;
    /* @param func function     Function to execute on ready
     * @param func Boolean      If true, all qeued functions are executed
     * @param b_before Boolean  If true, the func will added to the first
     position in the queue*/
    return function(func, b_before) {
        if (func === true) {
            api_isReady = true;
            for (var i = 0; i < onReady_funcs.length; i++) {
                // Removes the first func from the array, and execute func
                onReady_funcs.shift()();
            }
        }
        else if (typeof func == "function") {
            if (api_isReady) func();
            else onReady_funcs[b_before ? "unshift" : "push"](func);
        }
    }
})();
// This function will be called when the API is fully loaded

function onYouTubePlayerAPIReady() {
    YT_ready(true)
}

var players = {};
//Define a player storage object, to enable later function calls,
//  without having to create a new class instance again.
YT_ready(function() {
    $(".thumb + iframe[id]").each(function() {
        var identifier = this.id;
        var frameID = getFrameID(identifier);
        if (frameID) { //If the frame exists
            players[frameID] = new YT.Player(frameID, {
                events: {
                    "onReady": createYTEvent(frameID, identifier)
                }
            });
        }
    });
});

// Returns a function to enable multiple events
function createYTEvent(frameID, identifier) {
    return function (event) {
        var player = players[frameID]; // player object
        var the_div = $('#'+identifier).parent();
        the_div.children('.thumb').click(function() {
            var $this = $(this);
            $this.fadeOut().next().addClass('play');
            setTimeout(function(){
                $this.siblings('.thumb').hide();
            },150);
            if ($this.next().hasClass('play')) {
                player.playVideo();
                //player.destroy();
            }
        });
    }
}

// Load YouTube Frame API
(function(){ //Closure, to not leak to the scope
    var s = document.createElement("script");
    s.src = "http://www.youtube.com/player_api"; /* Load Player API*/
    var before = document.getElementsByTagName("script")[0];
    before.parentNode.insertBefore(s, before);
})();
.y-video{
  position: relative;
  display: block;
  width: 500px;
  clear: left;  
}
.play-icon{
    display: inline-block;
    position: absolute;
    left: 0;
    right: 0;
    margin: 0 auto;
    top: 42%;
    z-index: 1;
    width: 40px;
    font-size: 26px;
    border: 2px solid #fff;
    border-radius: 50%;
    text-align: center;
    color: rgba(255,255,255,0.4);
    padding: 4px 0 4px 5px;
    cursor: pointer;
    background: rgba(0,0,0,.1);
    -webkit-transition: 0.4s;
    -moz-transition: 0.4s;
    transition: 0.4s;
  }
img.thumb{
    position: absolute;
    width: 100%;
    height: auto;
    max-height: 281px;
    left: 0;
    top: 0;
}
.y-video:hover .play-icon{   
      border-color: rgba(0,0,0,.1);
      background: rgba(0,0,0,.6);
      color: rgba(255,255,255,0.8);   
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="y-video">
 <span class="thumb play-icon">&#9655;</span>
 <img class="thumb" src="http://img.youtube.com/vi/gpzuVt_mkKs/0.jpg">
 <iframe width="500" height="281" frameborder="0" src="https://www.youtube.com/embed/gpzuVt_mkKs?enablejsapi=1&showinfo=0&rel=0">
 </iframe>
</div>

<div class="y-video">
 <span class="thumb play-icon">&#9655;</span>
 <img class="thumb" src="http://img.youtube.com/vi/Ep6U7vGjFw0/0.jpg">
 <iframe width="500" height="281" frameborder="0" src="https://www.youtube.com/embed/Ep6U7vGjFw0?enablejsapi=1&showinfo=0&rel=0">
 </iframe>
</div>

<div class="y-video">
 <span class="thumb play-icon">&#9655;</span>
 <img class="thumb" src="http://img.youtube.com/vi/6lt2JfJdGSY/0.jpg">
 <iframe width="500" height="281" frameborder="0" src="https://www.youtube.com/embed/6lt2JfJdGSY?enablejsapi=1&showinfo=0&rel=0">
 </iframe>
</div>
kravisingh
  • 1,640
  • 12
  • 16