Last active
October 10, 2015 23:31
-
-
Save haziqAhmed7/772ca9e70706b2229ff5 to your computer and use it in GitHub Desktop.
Play multiple videos without playlist in Youtube Iframe Api v3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The Functionality would be to Fetch the Playlist from the registered user | |
* then wrap the data into the Youtube Player and bind the event so that | |
* it can play the playlist according to the videos offset which are essential for this | |
* application | |
* Created by Haziq on 9/27/2015. | |
*/ | |
//Variables to remember states | |
var data; | |
var playlist_name, date, count, tracks, start, end = []; | |
playlist_name = []; date = []; count = []; tracks = []; start = []; end = []; | |
//Youtube player array | |
var Player = []; | |
/** | |
* Getters and Setters for the global data containing server response | |
*/ | |
function getData() | |
{ | |
return data; | |
} | |
function setData(response) | |
{ | |
data = response; | |
} | |
/** | |
* As the scripts function is dependent on the Api which will be fetched by the Youtube Server | |
* So we need a function that will authenticate that the script is downloaded and ready to use in | |
* order to fire our methods | |
* This function will basically wait for the script to download for this purpose recursive methods | |
* will be used for watitng along with the timeout functionality | |
* once the script has loaded the control will be headed towards the other core functions | |
*/ | |
function authenticateScriptDownload() | |
{ | |
//First initiate function to retrieve the script from the google | |
identify_library(); | |
//wait until the script is fetched | |
setTimeout(function() | |
{ | |
//check whether the script is loaded by checking the length of script tag and class object | |
if($.isFunction(YT.Player)) //if( typeof(YT.Player) != 'undefined' ) | |
{ | |
//our script is loaded and ready to use | |
console.log("Script is loaded"); | |
//once the script is loaded call other script functions but first consider the response is loaded | |
if(getData().length > 0) | |
{ | |
// use the setters to retrieve the script global property | |
refine(getData()); | |
split_organize(); | |
console.log(getData()); | |
} | |
else | |
{ | |
console.log("No response is provided against playlist tasks"); | |
} | |
} | |
else | |
{ | |
//Since the script is still loading we can wait | |
console.log("Script still loading"); | |
authenticateScriptDownload(); | |
} | |
}, 600); | |
} | |
/** | |
The Purpose of this function is to refine the ajax response , separate each field and save them into an | |
individual array. | |
Further more this function is also responsible for changing the DOM elements which are described as follow. | |
This function will create the child div for every playlist iteration in the main "Playlist" div. | |
the child div will contain heading (playlist name) and another div which will then be forwarded to the Youtube Api | |
for its processing | |
The id for the div which will be used by the youtube will start from 'p' followed by the playlist name. | |
*/ | |
function refine(data) | |
{ | |
//fetch every playlist in iteration | |
for(var i=0; i<data.length; i++) | |
{ | |
//get Playlist Name, Date, count of songs in a playlist | |
console.log(data[i]['Name']); | |
playlist_name[i] = data[i]['Name']; | |
date[i] = data[i]['Date']; | |
count[i] = data[i]['Count']; | |
//initialize the variables to get the video offsets, codes from the individual playlist | |
var Start,End,Tracks = ""; | |
//Get Playlist tracks | |
for(var j=0; j < parseInt(count[i]); j++) | |
{ | |
//Get the video offsets, codes from the response | |
Start = data[i]['Tracks'][j]['StartTime'] + ','; | |
End = data[i]['Tracks'][j]['EndTime'] + ','; | |
Tracks = data[i]['Tracks'][j]['SongID'] + ','; | |
} | |
//Remove the last separators ',' from the data and save them in to the array for safe keeping | |
start[i] = Start.replace(/,\s*$/, ""); | |
end[i] = End.replace(/,\s*$/, ""); | |
tracks[i]= Tracks.replace(/,\s*$/, ""); | |
//Create a new DOM element <div>, <p> tag and add it in the playlist <div> | |
var element = '<div id="'+playlist_name[i] + '" > <p > '+ playlist_name[i] + '<p/> <div id="v'+playlist_name[i]+ | |
'" <div/> <div/>'; | |
$("#Playlist").append(element); | |
} | |
} | |
/** | |
* The purpose of this function is to split the whole array into individual playlist so it the each player | |
* can have its own responsibility. | |
* The array which would be split will contain the songs ID, video offsets in an individual data structures | |
*/ | |
function split_organize() | |
{ | |
//Iterate through every index of playlist array and split this according to the total count of the array | |
//Actually as we created above the DOM elements so we would iterate the DOM elements instead of using the formal loop | |
//Initialize the indexer variable to iterate the values in the array | |
var counter = 0; | |
//Using the map function to iterate the inner child divs of the Playlist div | |
setTimeout(function() | |
{ | |
//check whether the script is loaded by checking the length of script tag and class object | |
if($.isFunction(YT.Player) ) | |
{ | |
//our script is loaded and ready to use | |
$("#Playlist > div").map(function() | |
{ | |
//Get the ID of every inner child | |
var id = this.id; | |
console.log("ID "+id); | |
var videoID = 'v' +id; | |
//Splitting of the array code starts here | |
var playlist_songs, video_start, video_end; | |
playlist_songs = tracks[counter]; | |
video_start = start[counter]; | |
video_end = end[counter]; | |
//Instantiate player here and bind on the created div | |
console.log("Initializing objects"); | |
$("#"+videoID).on( Create_Player(playlist_songs, video_start, video_end, counter, videoID) ); | |
//increment the indexer value | |
counter++; | |
}); | |
} | |
else | |
{ | |
//Since the script is still loading we can wait | |
console.log("Script still loading and passed 1st iteration"); | |
split_organize(); | |
} | |
}, 300); | |
} | |
/** | |
The purpose of this function is to Instantiate the Youtube Player object in the inner child of the Playlist <div> | |
The object instantiated will be provided four arguments | |
1) list of video ID's | |
2) Each videos starting offset | |
3) Each videos ending offset | |
4) Current index of the playlist | |
5) ID of the DOM element in which the player object will reside | |
After passing the arguments in the object creation the next step would be to bind that object in an event | |
The binding will be against the onPlayerStateChange(event) event | |
*/ | |
function Create_Player(songs, start, end, counter, element_id) | |
{ | |
//create a property to iterate through next videos | |
var indexer = 0; | |
//create the property to record the previous index | |
var previous; | |
//remove the impurity and store them in an array | |
songs = songs.split(','); | |
start = start.split(','); | |
end = end.split(','); | |
//First check whether the library is available for creating Youtube object | |
identify_library(); | |
//create the Youtube Player here specify height of the player and provide event function names | |
Player[counter] = new YT.Player(element_id, | |
{ | |
height: '320', | |
width: '480', | |
events: { | |
'onReady': onPlayerReady, | |
'onStateChange': onPlayerStateChange | |
} | |
}); console.log('# '+ counter + Player[counter]); | |
//---event function-- When the player is ready fire this one | |
function onPlayerReady(event) | |
{ | |
//load video by the Youtube api provided function accepted arguments are VideoID, Video offsets | |
Player[counter].loadVideoById( { 'videoId': songs[indexer], | |
'startSeconds':start[indexer], | |
'endSeconds': end[indexer] | |
}); | |
//once all the arguments are supplied fire the method to start video | |
event.target.playVideo(); console.log("video is playing"); | |
Player[counter].playVideo(); | |
//record the indexer value | |
previous = indexer; | |
//Increment the indexer property so to play the next video. | |
indexer += 1; | |
} | |
//---event function-- When the player change state fire this one | |
function onPlayerStateChange(event) | |
{ | |
//get current time of the playing video | |
var currentTime = Player[counter].getCurrentTime(); | |
//check if the current time exceeds the video offset if so then load next video and update fields also check | |
//that if the indexer property exceeds the total length of the songs array if so then stop the player | |
if( (currentTime > end[indexer] || currentTime == end[indexer]) && indexer < songs.length ) | |
{ | |
//load next video and update the properties | |
Player[counter].stopVideo(); | |
Player[counter].loadVideoById({ | |
'VideoId':songs[indexer], | |
'startSeconds':start[indexer], | |
'endSeconds': end[indexer] | |
}); | |
Player[counter].playVideo(); | |
previous = indexer; | |
indexer += 1; | |
} | |
else if(indexer >= songs.length) | |
{ | |
Player[counter].stopVideo(); | |
} | |
} | |
} | |
/** | |
* The purpose of this function is to identify the availability of script tag from Youtube api | |
* if the tag exists then return false else create the tag and import the youtube api iframe library | |
*/ | |
function identify_library() | |
{ | |
//check the library existence | |
if($("#script").length) | |
{ | |
console.log("Library exists"); | |
//library exist | |
return false; | |
} | |
else | |
{ | |
//library doesn't exist fetch the code from the Youtube | |
var tag = document.createElement('script'); | |
tag.src = "https://www.youtube.com/iframe_api"; | |
var firstScriptTag = document.getElementsByTagName('script')[0]; | |
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); | |
console.log("Library Fetched"); | |
setTimeout(function(){}, 200); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment