SoundCloud players have a default functionality where when a user starts a player, it automatically pauses all others that are currently playing. (example: /).
I'm trying to recreate this with embedded youtube videos that are added dynamically via the normal embed code.
Using this: and this:
I'm able to get this far:
function chain(){
$('.post').each(function(){
var player_id = $(this).children('iframe').attr("id");
var other_player_id = $(this).siblings().children('iframe').attr("id");
player = new YT.Player( player_id, {
events:
{
'onStateChange': function (event)
{
if (event.data == YT.PlayerState.PLAYING)
{ callPlayer( other_player_id , 'pauseVideo' );
alert('Trying to pause: ' + other_player_id);
}
}
}
});
});
}
Here's a JS Bin with it half working:
Currently, its only calling one of the players. I need it to pause ALL of the other players except the playing one.
Also, any tips on how to clean this up and/or do it differently/better are wele. I'm still very new to javascript so I'm not even sure I'm going about it the right way.
Thanks!
SoundCloud players have a default functionality where when a user starts a player, it automatically pauses all others that are currently playing. (example: http://jsfiddle/Vx6hM/).
I'm trying to recreate this with embedded youtube videos that are added dynamically via the normal embed code.
Using this: https://stackoverflow./a/7513356/938089 and this: https://stackoverflow./a/7988536/1470827
I'm able to get this far:
function chain(){
$('.post').each(function(){
var player_id = $(this).children('iframe').attr("id");
var other_player_id = $(this).siblings().children('iframe').attr("id");
player = new YT.Player( player_id, {
events:
{
'onStateChange': function (event)
{
if (event.data == YT.PlayerState.PLAYING)
{ callPlayer( other_player_id , 'pauseVideo' );
alert('Trying to pause: ' + other_player_id);
}
}
}
});
});
}
Here's a JS Bin with it half working: http://jsbin./oxoyes/2/edit
Currently, its only calling one of the players. I need it to pause ALL of the other players except the playing one.
Also, any tips on how to clean this up and/or do it differently/better are wele. I'm still very new to javascript so I'm not even sure I'm going about it the right way.
Thanks!
Share Improve this question edited May 23, 2017 at 10:27 CommunityBot 11 silver badge asked Oct 21, 2012 at 2:39 MyeMye 551 silver badge5 bronze badges 1- I wrote a blog post that details a full working example of responding to various Youtube player API events: objectpartners./2013/08/21/… – Nate Flink Commented Aug 23, 2013 at 18:10
3 Answers
Reset to default 2You'll only have at most one player playing at a given time. Instead of trying to pause all that are playing, think of it as trying to pause the one playing. Of course, none could be playing. Given this, take a look at the following code. You maintain a single outer scope variable and pause that when necessary, while setting it to the player you just started playing thereafter.
var playerCurrentlyPlaying = null;
function chain(){
$('.post').each(function(){
var player_id = $(this).children('iframe').attr("id");
player = new YT.Player( player_id, {
events:
{
'onStateChange': function (event)
{
if (event.data == YT.PlayerState.PLAYING)
{
if(playerCurrentlyPlaying != null &&
playerCurrentlyPlaying != player_id)
callPlayer( playerCurrentlyPlaying , 'pauseVideo' );
playerCurrentlyPlaying = player_id;
}
}
}
});
});
}
I think this might achieve your solution
var players=[];
function chain(id){
var player_id = $('#player'+id).attr('id');
players[id]=new YT.Player( player_id, {
events:
{
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event){
var playerid=$(event.target).attr('id');
if(event.data!=-1 && event.data!=5){
for(i=1;i<players.length;i++){
if(playerid!=i){
players[i].stopVideo();
}
}
}
}
the problem with your previous code was that you where using each in call function so it might execute 3*3 times so creating 9 instances of the player.So what i have done is that i am storing each instance in an array.
demo: http://jsbin./oxoyes/11/edit
I tried the way posted by cbayram and found it to have spotty success. I preferred fuzionpro's way but had to correct a few problems w/ it and I came up w/ the following, which works well and includes console.logs so you can see whats happening. Probably bining ytPlayers and ytPlayerStates below would make it more efficient.
// load the IFrame Player API code asynchronously
var tag = document.createElement('script');
tag.src = "https://www.youtube./iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var ytPlayers = new Array();
var ytPlayerStates = new Array();
window.onYouTubePlayerAPIReady = function()
{
jQuery('.video-container>iframe').each(function(index)
{
var iframeID = jQuery(this).attr('id');
ytPlayerStates[iframeID] = -1;
(function (iframeID) {
ytPlayers.push(new YT.Player(iframeID, {
events:
{
'onStateChange' : function (event)
{
console.log(iframeID+' '+event.data);
if (event.data == 1)
{
ytPlayerStates[iframeID] = 1;
for (var key in ytPlayerStates)
{
if (key != iframeID)
{
if (ytPlayerStates[key] == 1 || ytPlayerStates[key] == 3)
{
ytPlayerStates[key] = 2;
callPlayer(key, 'pauseVideo')
}
}
console.log(key+' : '+ytPlayerStates[key]);
};
}
}
}
}));
})(iframeID);
});
}