Building Youtube Instant Just Like Google Instant!

This entry was posted on Thursday, October 6th, 2011 and is filed under apps, JavaScript, JSON.

We all like Google Instant and YouTube Instant Created by Feross Aboukhadijeh. So lets learn how to build a YouTube Instant just like Google Instant. Let us use JSON for retrieving videos from YouTube.

What is Google Instant?

Google Instant saves users average search time by 10 sec. Whenever we start typing, we can see search result of the first relevant Google Suggest. Results change automatically as we continue.

Understanding YouTube JSON Suggest

http://suggestqueries.google.com/complete/search?%20hl=en&ds=yt&json=t&jsonp=queryfunc&q=QUERY

["' value",["valuev","values","valuev knockout","value investing","valuev vs klitschko","valuev vs haye","values commercial","value of time","values commercial foundation for a better life","value stream mapping"],["","","","","","","","","",""]]

The above is JSON response for QUERY=Value

We all know JSON has an optional callback so I have specified a function by name queryfunc. Whenever we specify callback, callback function is called with JSON contents as parameter. Now let us write queryfunc for parsing YouTube JSON search suggest and getting first result from that.

function queryfunc(result) {
	//In this function we pass the JSON generated by Instant Function
	//From this function we get 1st value from Suggest
	// We initialize a variable Key
	var key = false;
	// We introduce a delay so that we can smoothly get reults
	for(j=0;j<100;j++);
	// result[1].length gives No of suggest available for particular query
	for (i=0; i<result [1].length; i++)
	{
// If there is an suggesion
if (result [1] [i].toLowerCase ())
	{
	// As there is a suggest for given query we initialize Key to True
	key = true;
	// We store value in firstsuggest variable
	var firstsuggest=result [1] [i].toLowerCase ();
	//search yotube with firsrtsuggest
	}
	}
	//if No Suggest found then clear instantinput div
		if(!key)
		{
		//perform exact search
		}
}

Idea of Building YouTube Instant Search

In building YouTube Instant, we will make use of two text boxes overlapped with each other. One text box in the background is read only and user cannot modify the data inside this box. In the read only text box, we will show first suggest of the YouTube to users. In the other text box, whenever the user presses a key the function is called with the value of textbox.

<style type="text/css">
#instantinput{
/*This CSS is an important part of project
We use Z index to show the suggest behind current text box.
*/
width:419px ;
height:35px;
position:absolute;
color:  #ccc;
z-index:-1;
background:url(http://www.highesthits.com/123.jpg)  no-repeat left top;
border:none;
font-family: "Segoe UI", Tahoma, Verdana,  Arial;
font-size: 16px;
}
#input {
/* We make use of two input text box
one is readonly */
width:419px ;
height:35px;
color:  #000;
background:transparent;
border:none;
font-family:  "Segoe UI", Tahoma, Verdana, Arial;
font-size: 16px;
}
</style>
<input type="text" id="instantinput" autocomplete="off"   value=" " readonly="readonly"/>
<input id="input" onkeyup="instant(this.value);"  type="text" /> 

We need to construct a Suggest URL each time. So lets write a function that takes users data and generates URL and then calls queryfunc.

function instant(value) {	
	if(!value)
	{
	//If there is no input then clear the screen
	document.getElementById('instantinput').value='';
	document.getElementById('videoResults').innerHTML='';
	setdisable();
	return;
	}
	//This function is called as soon as user presses a key
	query = 'http://suggestqueries.google.com/complete/search?%20hl=en&ds=yt&json=t&jsonp=queryfunc&q='+value;


//query contains url of the Youtube Suggest in JSON format we later parse this with queryfunc to get 1st value
	var script = document.createElement ('script');
	script.setAttribute ('src', query);
	script.setAttribute ('type','text/javascript');
	document.getElementsByTagName ('head') [0].appendChild (script);
	//The above 3 line code automattically  call the query URL
	//So overall this function creates a URL for the query which user has typed
}

So whenever we press a key, Function Instant is called which in turn asynchronously calls queryfunc with JSON file as parameter.
Lets now build a YouTube JSON Search. For more details about YouTube JSON API Please Check Here .
Dynamically Generating YouTube Search URL
YouTube JSON Search URL is http://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc&q=QUERY&callback=ytresult&max-results=6&start-index=1. Here QUERY refers to search query, alt=jsonc refers to JSONC format,Callback is used to specify callback function.
Function for generating Dynamic YouTube URL

function ytsearch(searchquery)
{  
  //This function takes input from queryfunc
  //It searches for input which it took from queryfunc
  var  script = document.createElement('script');
  script.setAttribute('id',  'JSON');
  script.setAttribute('type',  'text/javascript');
  //Let us initialize searchkey to query
  if(searchquery)
  //assign new value to search key only when available
  searchkey=searchquery;
  //We construct URL using searchquery for obtaining JSON results
  var url='http://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc&q='+searchkey+'&callback=ytresult&max-results=6;
  script.setAttribute('src',url);
  document.documentElement.firstChild.appendChild(script);
  //We call the URL which we constructed above 
  //We call ytresult function to retrive the result of JSON
}

Now Let us write ytresult function to get contents from YouTube

function ytresult(results)
{
	//We use this function to parse Youtube Search Result
	//Youtube JSON results are in JSONC format
	//All the components are wrapped inside result Array
	//Let use use a array to store the parsed data
	var html = [ ];
	//results.data.items.length contains No of Search Results
	if(results.data.items.length<6)
	setdisable();
	else
	document.getElementById('next').disabled=false;
	
	for (var i = 0; i < results.data.items.length; i++)
	{
		//Now let us convert time in Seconds to Hour:Minute:Second format
		if(results.data.items[i].duration) {
		duration = results.data.items[i].duration;
		//Initially we set hours,minutes and second all to zero
		hours = 0;
		minutes = 0;
		seconds = 0;
		//If duration > 3600 sec then we increase hour count
		// We increase count untill duration is less than 3600
		while(duration >= 3600) {
		hours = hours + 1;
	    duration = duration - 3600;
        }
		//suppose we have duration more than 60 sec then we increment minute count
		//We increase count untill duration is less than 60 sec
		while(duration >= 60) {
                    minutes = minutes + 1;
                    duration = duration - 60;
                  }
		seconds = duration;
		//if duration of video is less than 10 sec then we directly  write it in M:S
	    if(seconds < 10) {
		seconds = '0'+seconds;
					}
		//We store the duration in Variable Time 
		time = minutes+':'+seconds;
		if(hours > 0) {
		time = hours+':'+time;
			}
		}
		// Now let us derive Title, Duration, Label, Thumbnail URL from JSON Feed
		var title = '<div id=tile>'+results.data.items[i].title;
		var views ='<br/>'+results.data.items[i].viewCount+' views</br>';
		var label = 'Label:- '+results.data.items[i].category =='undefined' ? 'undefined' : results.data.items[i].category;
		var duration = '</br> Duration:- '+time;
        var image  = "<img src = "+results.data.items[i].thumbnail.sqDefault+">";
		var vid =results.data.items[i].id;//Video id of Video
        var urlvalue = '<br/><a id="light" class="example6" href = "http://www.highesthits.com/video.php?v='+ vid + '">'+image;
		//Once we have retrieved all neccessary information
		//We push the content variables in an order
        html.push('<div id=nannuin><table><tr><td>', urlvalue,'</td><td>',title, views, label, duration,  '</td></tr></table></div>');           
         }
            html.push('');
			//Now we apply contents of Array HTML to videoResult container
            document.getElementById('videoResults').innerHTML = html.join('');
	}

So in the final source code i have included features like Next, Previous, Disable Next and Previous, Clear Search result if Text Box is cleared, Bring content from read only text box to user input text box by pressing right arrow key. etc etc

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Youtube Instant Search</title>
<style>

html, body, div, ul {
	margin: 0;
	padding: 0;
}

body {
	text-align: center;
	font: 12px Verdana;
	color: #333333;
	background: transparent;
    padding:10px;
}


#content {
	background:transparent;
     height:auto;
	padding:10px;
	font: normal 12px/18px Verdana, sans-serif;
	-moz-box-shadow: 0px 0px 10px #cbcbcb;
	-webkit-box-shadow: 0px 0px 10px #cbcbcb;

}
#content .latest {
		padding: 10px 20px 10px 0;
		margin-bottom: 10px;
	}
#content .latest h2 {
			font-size: 1.5em;
			padding-right: 90px;
			padding-bottom: 15px;
		}

		#content .latest p {
			font-size: 0.9em;
			margin-bottom: 12px;
			line-height: 1.4em;
		}
#content .single ul {
	margin: 0 0 10px 18px;
}

#content .single ol {
	margin: 0 0 10px 20px;
}

	#content .single li {
		padding: 2px 0;
		line-height: 1.4em;
	}

	#content .single h3 {
		margin-bottom: 5px;
		font-size: 1.4em;
		font-size: 1.5em;
		font-weight: normal;
	}
	.single .details {
		padding: 20px 0;
	}
	.single .details p {
		margin-bottom: 5px !important;
	}

#wrapper {
	text-align: left;
	width: 720px;
	margin: auto;
}

h1 {
	margin: 30px 0 15px 0;
	font-size: 30px;
	font-weight: bold;
	font-family: Arial;
}

.break {
	font-size: 0;
	width: 0; height: 0;
	clear: both;
}

.alignleft {
	float: left;
	margin: 4px 10px 5px 0;

}

.alignright {
	float: right;
	margin: 4px 0 5px 10px;

}

.hidden {

	display: none;

}

.noimage img {

	display: none;

}
a {

	text-decoration: none;

	color: #000;

}

h1 span {
	font-size: 50%;
	letter-spacing: -0.05em;
}

hr {
	border: none;
	height: 1px; line-height: 1px;
	background: #E5E5E5;
	padding: 0;
}

p {
	margin: 0;
	padding: 7px 0;
}

a {
	outline: none;
}

a img {
	border: 1px solid #BBB;
	padding: 2px;
	margin: 10px 20px 10px 0;
	vertical-align: top;
}

a img.last {
	margin-right: 0;	
}

ul {
	margin-bottom: 24px;
	padding-left: 30px;
}
#content {
	padding-left:10px;
	clear: both;
	float: left;
	border-right: 1px solid #CCCCCC;
	width: 600px;
	padding:10px 10px 10px 10px;
    padding-left:15px;
    font-family:"Segoe UI", Tahoma, Verdana, Arial;
}
#instantinput{
/*This CSS is an important part of project
We use Z index to show the suggest behind current text box.
*/
width:419px ;
height:35px;
position:absolute;
color:  #ccc;
z-index:-1;
background:url(http://www.highesthits.com/123.jpg)  no-repeat left top;
 border:none;
font-family: "Segoe UI", Tahoma, Verdana,  Arial;
font-size: 16px;
}

#input {
/* We make use of two input text box
one is readonly */
width:419px ;
height:35px;
color:  #000;
background:transparent;
border:none;
font-family:  "Segoe UI", Tahoma, Verdana, Arial;
 font-size: 16px;
}
</style>
<script type="application/javascript">
//Developed by Raghavendra Nayak M
//http://www.highesthits.com
//Copyrights 2011 Raghavendra Nayak M 
//All Rights Reserved
var suggest;//This is a global variable which holds suggestion
var count=0;//This variable will have how many spaces left cursor has moved
var index=1;//Used for start index, necessary for previous and next
var searchkey;//This is usefull in doing next and previous 
function ytsearch(searchquery)
{  
  //This function takes input from queryfunc
  //It searches for input which it took from queryfunc
  var  script = document.createElement('script');
  script.setAttribute('id',  'jsonScript');
  script.setAttribute('type',  'text/javascript');
  //Let us initialize searchkey to query
  if(searchquery)
  //assign new value to search key only when available
  searchkey=searchquery;
  //We construct URL using searchquery for obtaining JSON results
  var url='http://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc&q='+searchkey+'&callback=ytresult&max-results=6&start-index='+index;
  script.setAttribute('src',url);
  document.documentElement.firstChild.appendChild(script);
  //We call the URL which we constructed above 
  //We call ytresult function to retrive the result of JSON
}
function ytresult(results)
{
	//We use this function to parse Youtube Search Result
	//Youtube JSON results are in JSONC format
	//All the components are wrapped inside result Array
	//Let use use a array to store the parsed data
	var html = [ ];
	//results.data.items.length contains No of Search Results
	if(results.data.items.length<6)
	setdisable();
	else
	document.getElementById('next').disabled=false;
	
	for (var i = 0; i < results.data.items.length; i++)
	{
		//Now let us convert time in Seconds to Hour:Minute:Second format
		if(results.data.items[i].duration) {
		duration = results.data.items[i].duration;
		//Initially we set hours,minutes and second all to zero
		hours = 0;
		minutes = 0;
		seconds = 0;
		//If duration > 3600 sec then we increase hour count
		// We increase count untill duration is less than 3600
		while(duration >= 3600) {
		hours = hours + 1;
	    duration = duration - 3600;
        }
		//suppose we have duration more than 60 sec then we increment minute count
		//We increase count untill duration is less than 60 sec
		while(duration >= 60) {
                    minutes = minutes + 1;
                    duration = duration - 60;
                  }
		seconds = duration;
		//if duration of video is less than 10 sec then we directly  write it in M:S
	    if(seconds < 10) {
		seconds = '0'+seconds;
					}
		//We store the duration in Variable Time 
		time = minutes+':'+seconds;
		if(hours > 0) {
		time = hours+':'+time;
			}
		}
		// Now let us derive Title, Duration, Label, Thumbnail URL from JSON Feed
		var title = '<div id=tile>'+results.data.items[i].title;
		var views ='<br/>'+results.data.items[i].viewCount+' views</br>';
		var label = 'Label:- '+results.data.items[i].category =='undefined' ? 'undefined' : results.data.items[i].category;
		var duration = '</br> Duration:- '+time;
        var image  = "<img src = "+results.data.items[i].thumbnail.sqDefault+">";
		var vid =results.data.items[i].id;//Video id of Video
        var urlvalue = '<br/><a id="light" class="example6" href = "http://www.highesthits.com/video.php?v='+ vid + '">'+image;
		//Once we have retrieved all neccessary information
		//We push the content variables in an order
        html.push('<div id=nannuin><table><tr><td>', urlvalue,'</td><td>',title, views, label, duration,  '</td></tr></table></div>');           
         }
            html.push('');
			//Now we apply contents of Array HTML to videoResult container
            document.getElementById('videoResults').innerHTML = html.join('');
	}
function queryfunc(result) {
	//In this function we pass the JSON generated by Instant Function
	//From this function we get 1st value from Suggest
	// We initialize a variable Key
	var key = false;
	// We introduce a delay so that we can smoothly get reults
	for(j=0;j<100;j++);
	// result[1].length gives No of suggest available for particular query
	for (i=0; i<result [1].length; i++) 
	{
		// If there is an suggesion 
			if (result [1] [i].toLowerCase ())
			{
				// As there is a suggest for given query we initialize Key to True
				key = true; 
				// We store value in firstsuggest variable
				var firstsuggest=result [1] [i].toLowerCase ();
				//Delay
				for(i=0;i<100;i++);
				//Output first suggest to instant input div
				document.getElementById ('instantinput').value=firstsuggest;
				suggest=firstsuggest;
				ytsearch(firstsuggest);
			}
	}
	//if No Suggest found then clear instantinput div
		if(!key)
		{
		document.getElementById ('instantinput').value='';
		//If instant option not available then search for exact result.
		ytsearch(result);
		}
}
function instant(value) {	
	if(!value)
	{
	//If there is no input then clear the screen
	document.getElementById('instantinput').value='';
	document.getElementById('videoResults').innerHTML='';
	setdisable();
	return;
	}
	//This function is called as soon as user presses a key
	query = 'http://suggestqueries.google.com/complete/search?%20hl=en&ds=yt&json=t&jsonp=queryfunc&q='+value;
	//query contains url of the Youtube Suggest in JSON format we later parse this with queryfunc to get 1st value
	var script = document.createElement ('script');
	script.setAttribute ('src', query);
	script.setAttribute ('type','text/javascript');
	document.getElementsByTagName ('head') [0].appendChild (script);
	//The above 3 line code automattically  call the query URL
	//So overall this function creates a URL for the query which user has typed
}
document. önkeydown=function(e){
	//This Function is used to provide Keyboard Function
	
if(e.which == 37)
//Whenever user press left arrow key increment counter
	{
		count++;
	}
if(e.which == 39 && count==0)
//Whenever user press right arrow key and count=0
//Copy suggestion to main input text box
{
	document.getElementById ('input').value=suggest;
}
if(e.which == 39 && count!=0)
//decrement when user press right arrow key and count !=0
		{
			count--;
		}
}
function setdisable()
{
	//We use this function to disable both next and previous button
	//We use this function at various instances
	document.getElementById('next').disabled=true;
	document.getElementById('prev').disabled=true;
}
function next()
{
	//We use this function to increment start index
	//After we perform next operation we enable previous button
	document.getElementById('prev').disabled=false;
	index+=6;
	ytsearch();
}
function prev()
{
	//We use this function to decrement start index
	//If value of start index is 7 then we further disable prev button
	if(index==7)
	{
	document.getElementById('prev').disabled=true;
	index-=6;
	ytsearch();
	}
	//We retrive the result using ytresult function
	else
	{
		index-=6;
		ytsearch();
	}
}
</script>
</head>
<div id="wrapper"> 
<div id="content"> 
<div class="latest single">
<input type="text" id="instantinput" autocomplete="off"   value=" " readonly="readonly"/>
<input id="input" onkeyup="instant(this.value);" on="sea() return false;" type="text" /> 
<div id="videoResults"></div>
<input  id="prev" type="submit" value="Prev" onclick="prev()"/>
<input id="next" type="submit" value="Next" onclick="next()"/>
</div>
</div>
</div>
<body onload="setdisable();">
</body>
</html>

You Might Also Like

Filed Under: apps, JavaScript, JSON