Click here to Skip to main content
15,895,256 members
Articles / Web Development / HTML

YouTube Dynamic AJAX / JSON Search API Demo

Rate me:
Please Sign up or sign in to vote.
4.73/5 (20 votes)
21 Jan 2013CPOL6 min read 72.7K   1.7K   41  
This article shows how to search dynamically for YouTube videos from your site, parse the JSON response, and embed videos.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<!-- saved from url=(0036)http://davidcodeproject.com/youtube/ -->
<HTML lang=en xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"><HEAD><TITLE>YouTube Dynamic AJAX Search API demo and Chromeless Play</TITLE>
<META http-equiv=Content-Type content="text/html; charset=utf-8">
<SCRIPT 
src="YouTube%20Dynamic%20AJAX%20Search%20API%20demo%20and%20Chromeless%20Play_files/jsapi"></SCRIPT>

<SCRIPT>
      google.load("swfobject", "2.1");
    </SCRIPT>
<!-- The utility for grids-->
<SCRIPT 
src="YouTube%20Dynamic%20AJAX%20Search%20API%20demo%20and%20Chromeless%20Play_files/os3grid.js"></SCRIPT>

<STYLE type=text/css>BODY {
	PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 135%; PADDING-TOP: 0px; TEXT-ALIGN: left
}
.sideBar {
	PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FLOAT: left; MARGIN-LEFT: 25px; WIDTH: 161px; MARGIN-RIGHT: 25px; PADDING-TOP: 0px
}
.mainContent {
	MARGIN: 0px 60px 0px 211px
}
#timedisplay {
	BORDER-RIGHT: red 1px solid; BORDER-TOP: red 1px solid; BORDER-LEFT: red 1px solid; WIDTH: 50px; BORDER-BOTTOM: red 1px solid
}
</STYLE>

<SCRIPT type=text/javascript>

	window.onkeydown = textBoxOnKeyDown;
	
	function textBoxOnKeyDown(e)
	{
		var keynum;
		var keychar;
		var numcheck;
	
		if(window.event) // IE
		{
	  		if (e.keyCode == 13)
		  		searchClicked()
	  }
		else 
		if(e.which) // Netscape/Firefox/Opera
	  {
	  		if (e.which == 13)
		  		searchClicked()
	  		
	  }
	}


		//&hd=1

		var gri = 0;
		function searchClicked()
		{
			

			// Create an OS3Grid instance
			g = new OS3Grid ();

			// Grid Headers are the grid column names
			g.set_headers ( 'constraint', 'result', 'search str', 'media secs', 'secs', 'view count', 'favorite count', 'avg rate', 'num raters', 'label',  'author', 'title', 'link', 'play' );
			//					0			1			2			3			  4			5					6		   7

			g.set_col_type(1, 'int');
			g.set_col_type(3, 'int');
			g.set_col_type(4, 'int');
			g.set_col_type(5, 'int');
			g.set_col_type(6, 'int');
			g.set_col_type(8, 'int');

			g.set_sortable ( true );
			g.set_highlight ( true );

			// If contents is bigger than container, Grid will automatically show scrollbars
			g.set_scrollbars ( true );

			gri = 0;

			var searchStr = document.getElementById('inputSearchStrId').value;
			var orderByCombo	= document.getElementById('order_by');
			var orderBy = orderByCombo.options[orderByCombo.selectedIndex].value;
			var optionsStr = "";
			
			optionsStr  += document.getElementById('checkBox_format5').checked ? "&format=5" : "";
			optionsStr  += document.getElementById('checkBox_fmt18').checked ? "&fmt=18" : ""; 
			insertVideos({'grid': g, 'block':'videoResultsDiv','q': searchStr,'results':document.getElementById('text_max_results').value,'orderby':orderBy, 'options': optionsStr});
		}



		function getVideoId(url)
		{				
				return url.substring(url.indexOf('=')+1,url.lastIndexOf('&'));
		}

		var requests = new Array();
		var lastRequest = 0;
		function insertVideos(cfg)
		{
			cfg = cfg || {};
			if(!cfg.block){
				//alert();
				return;
			}

			document.getElementById(cfg.block).innerHTML = 'Loading YouTube videos for ' + cfg.q + '...';
			//create a javascript element that returns our JSON data.
			var script = document.createElement('script');
			script.setAttribute('id', 'jsonScript');
			script.setAttribute('type', 'text/javascript');

			if(!cfg.results)
			{
				cfg.results = 10;
			}
			if(!cfg.sortorder)
			{
				cfg.sortorder = 'descending';
			}
			if(!cfg.orderby)
			{
				cfg.orderby = 'relevance';
			}

			requests[lastRequest] = function(root){showMyVideos(cfg, root);}
			script.setAttribute('src', 'http://gdata.youtube.com/feeds/videos?vq='+cfg.q+'&max-results='+cfg.results+'&alt=json-in-script&callback=requests[' + (lastRequest++) + ']&orderby='+cfg.orderby+'&sortorder='+cfg.sortorder+ cfg.options);
			//attach script to page, this will load the data into our page and call the funtion results[lastRequest]
			document.documentElement.firstChild.appendChild(script);
			
			// prepare a sample string
			var sourceCodeStr = "//...\nvar script = document.createElement('script');\nscript.setAttribute('id', 'jsonScript');\nscript.setAttribute('type', 'text/javascript');";
			var requestStr = 'http://gdata.youtube.com/feeds/videos?vq='+cfg.q+'&max-results='+cfg.results+'&alt=json-in-script&callback=showMyVideos&orderby='+cfg.orderby+'&sortorder='+cfg.sortorder+ cfg.options
			sourceCodeStr = sourceCodeStr + "\nscript.setAttribute('src', '" + requestStr + "');\n//attach script to page, this will call the funtion showMyVideos(data) and pass the response to it\ndocument.documentElement.firstChild.appendChild(script);";			
			document.getElementById("sourceCode").value = sourceCodeStr;

		}

	  var g;
		function showMyVideos(cfg, data)
		{
			var feed = data.feed;
			var entries = feed.entry || [];

			for (var i = 0; i < entries.length; i++)
			{
				var linkable = true;

				var entry = entries[i];
				var constraints = "";

				// also entries[3].media$group.media$content[0].duration
				// also entries[3].media$group.media$title.$t
				// sometimes does not work. entry.media$group.media$content[0].expression
				var duration = entry.media$group.yt$duration.seconds;
				var mediaDuration = typeof entry.media$group.media$content != 'undefined' ? entry.media$group.media$content[0].duration : '-1';
				if (entry.media$group.yt$duration.seconds <120)
					constraints += " less than 2 min ";

				if (typeof entry.yt$noembed != 'undefined')
					constraints += " NO EMBED ";

				var title = entry.title.$t;
				if (title.match("Live") || title.match("live") || title.match("LIVE"))
					constraints += " LIVE ";


				var vid = (getVideoId(entry.link[0].href));
				var lnk = "<a href = \"" + entry.link[0].href + "\">link</a>&nbsp;&nbsp;"
				var play  = "<a href = \"JavaScript:loadNewVideo('" + vid + "', 0);\">Play</a>"
				var a = "123";

				cfg.grid.add_row(constraints,
								 i,
								 typeof cfg.q =='undefined' ? 'undefined' : cfg.q ,
								 mediaDuration,
								 typeof duration =='undefined' ? 'undefined' : duration,
								 typeof entry.yt$statistics.viewCount == 'undefined' ? 'undefinded' : entry.yt$statistics.viewCount.valueOf(),
								 typeof entry.yt$statistics.favoriteCount == 'undefined' ? 'undefinded' : entry.yt$statistics.favoriteCount ,
								 typeof entry.gd$rating =='undefined' ? 'undefinded' : typeof entry.gd$rating.average =='undefined' ? 'undefined' : entry.gd$rating.average ,
								 typeof entry.gd$rating =='undefined' ? 'undefinded' : typeof entry.gd$rating.numRaters =='undefined' ? 'undefined' : entry.gd$rating.numRaters,
								 typeof entry.media$group.media$category[0].label =='undefined' ? 'undefined' : entry.media$group.media$category[0].label,
								 typeof entry.author[0].name.$t =='undefined' ? 'undefined' : entry.author[0].name.$t,
								 typeof entry.title.$t =='undefined' ? 'undefined' : entry.title.$t,
								 lnk,
								 play);

				if (constraints != '')
				{
					g.set_row_color('#222', gri);
				}
				gri++;


			}

			g.render(cfg.block);
			return;

		}


	</SCRIPT>

<SCRIPT type=text/javascript>
		function updateHTML(elmId, value) {
          document.getElementById(elmId).innerHTML = value;
        }

        function setytplayerState(newState) {
          updateHTML("playerstate", newState);
        }

        function onYouTubePlayerReady(playerId) {
          ytplayer = document.getElementById("myytplayer");
          setInterval(updateytplayerInfo, 250);
          updateytplayerInfo();
          ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
          ytplayer.addEventListener("onError", "onPlayerError");
        }

        function onytplayerStateChange(newState) {
          setytplayerState(newState);
        }

        function onPlayerError(errorCode) {
          alert("An error occured: " + errorCode);
        }

        function updateytplayerInfo() {
          updateHTML("bytesloaded", getBytesLoaded());
          updateHTML("bytestotal", getBytesTotal());
          updateHTML("videoduration", getDuration());
          updateHTML("videotime", getCurrentTime());
          updateHTML("startbytes", getStartBytes());
          updateHTML("volume", getVolume());
        }

        // functions for the api calls
        function loadNewVideo(id, startSeconds) {
          if (ytplayer) {
			var req =   id + (document.getElementById('player_arg').value != '' ? document.getElementById('player_arg').value : '');
            ytplayer.loadVideoById(req, parseInt(startSeconds));
          }
        }

        function cueNewVideo(id, startSeconds) {
          if (ytplayer) {
            ytplayer.cueVideoById(id, startSeconds);
          }
        }

        function play() {
          if (ytplayer) {
            ytplayer.playVideo();
          }
        }

        function pause() {
          if (ytplayer) {
            ytplayer.pauseVideo();
          }
        }

        function stop() {
          if (ytplayer) {
            ytplayer.stopVideo();
          }
        }

        function getPlayerState() {
          if (ytplayer) {
            return ytplayer.getPlayerState();
          }
        }

        function seekTo(seconds) {
          if (ytplayer) {
            ytplayer.seekTo(seconds, true);
          }
        }

        function getBytesLoaded() {
          if (ytplayer) {
            return ytplayer.getVideoBytesLoaded();
          }
        }

        function getBytesTotal() {
          if (ytplayer) {
            return ytplayer.getVideoBytesTotal();
          }
        }

        function getCurrentTime() {
          if (ytplayer) {
            return ytplayer.getCurrentTime();
          }
        }

        function getDuration() {
          if (ytplayer) {
            return ytplayer.getDuration();
          }
        }

        function getStartBytes() {
          if (ytplayer) {
            return ytplayer.getVideoStartBytes();
          }
        }

        function mute() {
          if (ytplayer) {
            ytplayer.mute();
          }
        }

        function unMute() {
          if (ytplayer) {
            ytplayer.unMute();
          }
        }

        function getEmbedCode() {
          alert(ytplayer.getVideoEmbedCode());
        }

        function getVideoUrl() {
          alert(ytplayer.getVideoUrl());
        }

        function setVolume(newVolume) {
          if (ytplayer) {
            ytplayer.setVolume(newVolume);
          }
        }

        function getVolume() {
          if (ytplayer) {
            return ytplayer.getVolume();
          }
        }

        function clearVideo() {
          if (ytplayer) {
            ytplayer.clearVideo();
          }
        }


    </SCRIPT>
<!-- Google analitics code -->
<SCRIPT type=text/javascript>
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</SCRIPT>

<SCRIPT type=text/javascript>
try {
var pageTracker = _gat._getTracker("UA-11314135-1");
pageTracker._setDomainName("none");
pageTracker._setAllowLinker(true);
pageTracker._trackPageview();
} catch(err) {}</SCRIPT>
<!-- End Google analitics code -->
<META content="MSHTML 6.00.6000.16587" name=GENERATOR></HEAD>
<BODY id=page>
<DIV class=sideBar><BR><BR><!--
		<script type="text/javascript"><!--
    google_ad_client = "pub-5497345139985875";
    /* 160x600 yt, created 10/29/09 */
    google_ad_slot = "6389178249";
    google_ad_width = 160;
    google_ad_height = 600;
    //--><!--
    </script>
    <script type="text/javascript"
    src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
    </script>
--></DIV>
<DIV class=mainContent>
<H1>Search YouTube Dynamically </H1>
<P><INPUT id=inputSearchStrId size=70 value="eminem we made you" name=searchStr> 
<LABEL for=order_by>Order&nbsp;By:</LABEL> <SELECT id=order_by name=order_by> 
  <OPTION value=relevance selected>relevance</OPTION> <OPTION 
  value=viewCount>viewCount</OPTION> <OPTION value=published>published</OPTION> 
  <OPTION value=rating>rating</OPTION></SELECT> &nbsp;&nbsp; <INPUT 
id=checkBox_format5 type=checkbox CHECKED name=format5> <LABEL 
for=checkBox_fmt18>&amp;format=5(excludes&nbsp;no&nbsp;embed)</LABEL> 
&nbsp;&nbsp; <INPUT id=checkBox_fmt18 type=checkbox CHECKED name=format> 
<LABEL>&amp;fmt=18( HQ)</LABEL> &nbsp;&nbsp; <LABEL 
for=text_max_results>max_results:</LABEL> <INPUT id=text_max_results 
style="WIDTH: 45px" value=8 name=text_max_results> <BR><INPUT onclick=searchClicked() type=submit value=Search name=searchButton> 
</P>Javascript code:<BR><TEXTAREA id=sourceCode style="WIDTH: 700px" rows=8 readOnly wrap=off cols=1>Click 'Search' to see the code for search request</TEXTAREA> 
<BR><BR>
<DIV id=videoResultsDiv 
style="BORDER-TOP-WIDTH: thick; BORDER-LEFT-WIDTH: thick; BORDER-BOTTOM-WIDTH: thick; BORDER-RIGHT-WIDTH: thick"></DIV>
<P><BR></P>
<P><B>How it Works:</B></P>
<P>The example above demonstrates dynamic AJAX search api of YouTube. Notice 
that when you click "Search" the results are loaded right into this page (you 
are not taken to another page as is the case with static searching) and the 
current page is not reloaded - hence the search is dynamic and makes use of 
AJAX. </P>
<P>Before reading the source of this page you might want to familiarize yourself 
with the <A 
href="http://code.google.com/apis/youtube/2.0/developers_guide_protocol_api_query_parameters.html">YouTube 
Search API Parameters</A> and <A 
href="http://code.google.com/apis/youtube/2.0/developers_guide_json.html">Youtube 
API: JSON / JavaScript</A>. They tell everything except how to make the search 
dynamic. </P>
<P>The response from YouTube in JSON format is passed asynchronously to 
javascript function showMyVideos(cfg, data). To see the source code from your 
browser do View Source or File-&gt;Save As, Web Page Complete and then view the 
page in any editor.&nbsp;</P>
<HR>

<H1>Chromeless Player Demo</H1>
<DIV>
<P>Click "Load Video" or "Cue Video" below to start playing a video. <BR>To play 
a different video, enter a YouTube video id and click "Load Video" or "Cue 
Video" again.</P><!-- embed the player -->
<DIV id=ytapiplayer>You need Flash player 8+ and JavaScript enabled to view this 
video. </DIV>
<SCRIPT type=text/javascript>
      // <![CDATA[

      // allowScriptAccess must be set to allow the Javascript from one
      // domain to access the swf on the youtube domain
      var params = { allowScriptAccess: "always", bgcolor: "#cccccc" };
      // this sets the id of the object or embed tag to 'myytplayer'.
      // You then use this id to access the swf and make calls to the player's API
      var atts = { id: "myytplayer" };
      swfobject.embedSWF("http://www.youtube.com/apiplayer?enablejsapi=1&playerapiid=ytplayer&fmt=18",
                         "ytapiplayer", "160", "120", "8", null, null, params, atts);
      //]]>
    </SCRIPT>
<!-- HTML below here is for display of the player info + state -->
<DIV>Player state: <SPAN id=playerstate>--</SPAN> </DIV>and<INPUT id=player_arg 
value=&amp;ap=%2526fmt%3D18 name=player_arg> 
<FORM id=form1 action="" method=post></FORM><BR><A onclick=play(); 
href="javascript:void(0);">Play</A> | <A onclick=pause(); 
href="javascript:void(0);">Pause</A> | <A onclick=stop(); 
href="javascript:void(0);">Stop</A> | <A onclick=mute(); 
href="javascript:void(0);">Mute</A> | <A onclick=unMute(); 
href="javascript:void(0);">Unmute</A> <BR><BR>
<FORM onsubmit="seekTo(document.getElementById('seekto').value); return false;" 
action="">
<DIV><INPUT id=seekto 
size=4><INPUT type=submit value="Seek to"></DIV></FORM><BR>
<DIV>Duration: <SPAN id=videoduration>--:--</SPAN> | Current Time: <SPAN 
id=videotime>--:--</SPAN> </DIV><BR>
<DIV id=bytesdisplay>Bytes Total: <SPAN id=bytestotal>--</SPAN> | Start Bytes: 
<SPAN id=startbytes>--</SPAN> | Bytes Loaded: <SPAN id=bytesloaded>--</SPAN> 
</DIV><BR>
<DIV><INPUT id=loadvideoid size=11 value=u1zgFlCw8Aw> <A 
onclick="loadNewVideo(document.getElementById('loadvideoid').value, document.getElementById('startseconds').value)" 
href="javascript:void(0)">&lt;- Load video</A> | Start at: <INPUT 
id=startseconds size=4 value=0> </DIV><BR>
<DIV><INPUT id=vol size=2> <A 
onclick="setVolume(document.getElementById('vol').value)" 
href="javascript:void(0)">&lt;- Set Volume</A> | Volume: <SPAN 
id=volume>--</SPAN> </DIV><BR>
<DIV><INPUT id=cuevideoid size=11 value=u1zgFlCw8Aw> <A 
onclick="cueNewVideo(document.getElementById('cuevideoid').value, document.getElementById('startseconds2').value)" 
href="javascript:void(0)">&lt;- Cue video</A> | Start at: <INPUT 
id=startseconds2 size=4 value=0> </DIV><BR>
<DIV><A onclick=getEmbedCode() href="javascript:void(0)">Get Embed Code</A> | <A 
onclick=getVideoUrl() href="javascript:void(0)">Get Video URL</A> | <A 
onclick=clearVideo() href="javascript:void(0);">Clear Video</A> 
</DIV></DIV><LINK href="os3grid.css" type=text/css rel=stylesheet><BR><BR>
<HR>
For questions or comments <BR>E-Mail: <A href="mailto:dalimian@gmail.com">David 
Alimian</A> </DIV></BODY></HTML>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions