Subscribe

Thursday 18 March 2010

YouTube Video Feed Slide-Show Gadget With JQuery Part 1

This is the first part in what is going to be a two or three part tutorial dealing with using the YouTube Feed API to create a slide show of videos which you prefer, not some random images but based on the search criteria or playlist or uploaded videos by the user of your choice.

Target For This Post
Part 1:
A java script class which can request a video feed from YouTube based on your selection criteria and then parse the feed returned to you. This will be done without any server-side script. The class can return an array which will have the following six attributes for each video.

thumb_title The title to be shown for the video
thumb_img The thumbnail which will represent the video
thumb_height The height of the thumbnail
thumb_width The width of the thumbnail
thumb_url The url of the video
vid Video Id used by youtube to identify a video uniquely
This class will have the following major methods
  • getUploadedVideos (username, format)
  • getSearchVideos(tag_txt, boolean_op, format)
  • getPlayListVideos(username, playlist, format)
  • startTubeSlideShow(player_div_id, seconds)
  • stopTubeSlideShow()
Technology Used
  1. Google Data API’s
  2. jQuery
  3. Javascript
  4. HTML
Google Data API has been used to request video RSS feed from the google or you-tube sever. The format which I have used is json-in-script format. For more details about this format please click here. The Google Data API has a very rich and fulfilling  structure. It can be modified in any way you want. If you are using proxies and are interested in getting an XML RSS feed no problem just add alt=rss to your request url and you will get in pure RSS 2.0 format. To learn more about this API you can visit here.
courtesy Google
Name Definition
alt The alt parameter specifies the format of the feed to be returned. Valid values for this parameter are atom, rss, json, json-in-script, and jsonc. The default value is atom and this document only explains the format of Atom responses. For more information about using API responses in JavaScript, please see Using JSON with Google Data APIs.
If you set the parameter value to json-in-script, then you must also set the
callback parameter value to identify the callback function to which the API response will be sent.
author In a search request, the author parameter restricts the search to videos uploaded by a particular YouTube user. Note that if you use this parameter when requesting a standard feed, then YouTube will retrieve the standard feed and then filter the response to only include videos uploaded by the specified author. For example, if you request the "Top Rated" feed for user GoogleDevelopers, the API will retrieve the top-rated feed and return a response containing videos in that feed uploaded by user GoogleDevelopers. The API will not return a list of that user's videos ordered by rating. 
In a request for a user activity feed, the author parameter contains a comma-separated list of up to 20 YouTube usernames. The API response will contain activities performed by any of those users.
callback The callback parameter identifies the callback function to which the API response will be sent. If the value of the alt parameter is jsonc or json-in-script, and you specify a value for the callback parameter, then the API response will be wrapped in a call to the specified function. This parameter is required if the value of the alt parameter is json-in-script.
max-results The max-results parameter specifies the maximum number of results that should be included in the result set. This parameter works in conjunction with the start-index parameter to determine which results to return. For example, to request the second set of 10 results – i.e. results 11-20 – set the max-results parameter to 10 and the start-index parameter to 11. The default value of this parameter is 25, and the maximum value is 50. However, for displaying lists of videos, we recommend that you set the max-results parameter to 10.
prettyprint The prettyprint parameter lets you request an XML response formatted with indentations and line breaks. Set the parameter's value to true to have the response formatted as such. The default parameter value is false.
start-index The start-index parameter specifies the index of the first matching result that should be included in the result set. This parameter uses a one-based index, meaning the first result is 1, the second result is 2 and so forth. This parameter works in conjunction with the max-results parameter to determine which results to return. For example, to request the second set of 10 results – i.e. results 11-20 – set the start-index parameter to11 and the max-results parameter to 10.
strict The strict parameter can be used to instruct YouTube to reject an API request if the request contains invalid request parameters. The default API behavior is to ignore invalid request parameters. If you want YouTube to reject API requests that contain invalid parameters, set the strictparameter value to true. For example, YouTube would reject the following request because "foo" is not a valid request parameter.
http://gdata.youtube.com/feeds/api/videos?foo=nonono&strict=true
v The v parameter specifies the version of the API that YouTube should use to handle the API request. Your request can specify the desired API version using either the v parameter or the GData-Version HTTP request header. All Google-provided client libraries always select a major API version. If your request does not specify an API version, YouTube will handle your request using API version 1. Please see the API versioningsection for more information about specifying an API version.

Say for instance you want to search for videos with a tag India the URL will be something like this
http://gdata.youtube.com/feeds/videos?alt=json-in-script&callback=?&q=India
In our case due to the use of jQuery which provides a call back for us we leave the callback value blank, but remember if you do not provide a question mark infront of the call back the computer will not make any request because of the strange way jQuery works.(I am not complaining).
jQuery has a method called . This method is wonderful and my new favourite because if any feed returns JSON then you can use getJSON to make a cross domain XMLHTTPRequest without those proxies and server side code. Yes it does take advantage of a security hole in the browser. However I believe very soon such requests will become a common place occurrence if it is not already so.
Essentially I ask jquery to brig some result and then I parse it using javascript. Because getJSON can work Asynchronously therefore my whole website is not blocked and I can assign a call back function which is fired when the server returns the data. Again the beauty of javascript is I can use anonymous functions as a call back instead of separate functions.
jQuery.getJSON( url, [ data ], [ callback(data, textStatus) ] )
urlA string containing the URL to which the request is sent.
dataA map or string that is sent to the server with the request.
callback(data, textStatus)A callback function that is executed if the request succeeds.


HTML has been used to create the front end and is inserted in the document as and when required by the various parts.

Short-coming
I have used few global variables to make my life easier, if you find any other method to overcome the problems please feel free to mail me.
The CSS is amateurish if not childish but the beauty of this code is you can change the CSS to suit your own fancies.


simpleTube.js
This file has the code which connects with Google to request anything that you require

SimpleTube this is the class which is has the functions dealing with playlist,search and uploaded videos.

getUploadedVideos Bring all the videos which are publicly available from a particular user


this.getUploadedVideos = function(username, format) {     
        var q = "http://gdata.youtube.com/feeds/api/users/" + username + "/uploads?alt=json-in-script&callback=?" ;
        if (format == '5') { 
            q += "&format=5";
        } 
        $.getJSON(q, function(json) {
            var htmlstr = ''; 
            tube_data = new Array(json.feed.entry.length);
            $.each(json.feed.entry, function(i, pl_item) {
                  tube_data[i] = new Array(6);
                if (pl_item['app$control'] != undefined && pl_item['app$control']['yt$state'] != undefined) {
  
                   var thumb = pl_item['app$control']['yt$state']['$t'];
                   var url = '#';
                   tube_data[i]["thumb_url"] = '#';
                   tube_data[i]["vid"] = pl_item['app$control']['yt$state']['$t'];
  
                } 
                else {
                    tube_data[i]["thumb_title"] = pl_item['title']['$t'];
                    tube_data[i]["thumb_img"] = pl_item['media$group']['media$thumbnail'][0]['url'];
                    tube_data[i]["thumb_width"] = pl_item['media$group']['media$thumbnail'][0]['width'];
                    tube_data[i]["thumb_height"] = pl_item['media$group']['media$thumbnail'][0]['height'];
                   tube_data[i]["thumb_url"] = pl_item['media$group']['media$player'][0]['url']
                  var vid_1 = tube_data[i]["thumb_url"].search('v=');
                  var vid_2 = tube_data[i]["thumb_url"].search('&feature');
                  var vid_len = vid_2 - (vid_1 + 2);
                 tube_data[i]["vid"] = tube_data[i]["thumb_url"].substr(vid_1 + 2, vid_len);
  
                } 

            }); 


        });

  
    }
This function is the easiest one as it accepts a username and the format(I will explain it later). The username is the user whose video you want to watch. As long as there is no restriction placed by the uploader you can easily get all the videos. Once we get the videos we parse the JSON in a double dimension array. for the first part we will not do anything with this array in the next part I will show you how to use this array. Format, if you place 5 as the format parameter then all the videos which cannot be embedded and are blocked or removed, are not included in the search, thus it brings only those videos which can be embedded.
$.getJSON(q, function(json) {
in this line I make a call to youtube for the videos and when the query returns with result the anonymous function gets called which has the result in the variable called json.

$.each(json.feed.entry, function(i, pl_item) {
for each entry of the feed an anonymous function is called which has a counter i, incremented automatically and that particular entry in the variable called pl_item.

if (pl_item['app$control'] != undefined && pl_item['app$control']['yt$state'] != undefined) {


checks to make sure that the video thus available can be used and is not blocked or removed. If the video has a problem then the thumb_url property is given a value of #. this will be used later to filter out the undesired content.

tube_data[i]["vid"] = pl_item['app$control']['yt$state']['$t'];


this stores the reason if any for the video being not available. If the video is usable then the five properties thumbnail width,height,and the src with video url and title are stored then we parse the url string for the VID or the video id used by youtube to uniquely identify a video and needed for loadind a video in a player.


getSearchVideos bring all the videos according to the tags and the boolean operator specified. Three operators are possible and or and random. If you say rand or random then the number of tags and the tags are chosen randomly thus each time the video might be a bit different.


this.getSearchVideos = function(tag_txt, boolean_op, format) {
        var tag_arr = tag_txt.split(',');
        var q = "http://gdata.youtube.com/feeds/videos?max-results=40&alt=json-in-script&callback=?&orderby=relevance&sortorder=descending&q=";

        var j = 0;

        var k = 0;

        var qstring = '';
        if (boolean_op == 'and') {

            qstring = "%22" + tag_arr[0];

            for (k = 1; k < tag_arr.length; k++) {

                qstring += "+" + tag_arr[k];

            }

            qstring += "%22";

        }

        if (boolean_op == 'or') {

            qstring = tag_arr[0];

            for (k = 1; k < tag_arr.length; k++) {

                qstring += "%7c" + tag_arr[k];

            }

        }

        if (boolean_op == 'rand') {
            var randomnumber = Math.floor(Math.random() * (tag_arr.length - 1)) + 1;
            qstring = tag_arr[randomnumber];
            for (k = 0; k <= randomnumber; k++) {
                randomnumber = Math.floor(Math.random() * tag_arr.length);
                qstring += "%7c" + tag_arr[randomnumber];

            }

        }


        q = q + qstring;

        if (format == '5')

            q += "&format=5";
        $.getJSON(q, function(data) {

            var htmlstr = '';

            tube_data = new Array(data.feed.entry.length);

            $.each(data.feed.entry, function(i, feed_item) {

                tube_data[i] = new Array(6);

                if (feed_item['app$control'] != undefined && feed_item['app$control']['yt$state'] != undefined) {

                    var thumb = feed_item['app$control']['yt$state']['$t'];

                    var url = '#';

                    tube_data[i]["thumb_url"] = '#';

                    tube_data[i]["vid"] = feed_item['app$control']['yt$state']['$t'];

                }

                else {

                    tube_data[i]["thumb_title"] = feed_item['title']['$t'];
                    tube_data[i]["thumb_img"] = feed_item['media$group']['media$thumbnail'][0]['url'];
                    tube_data[i]["thumb_width"] = feed_item['media$group']['media$thumbnail'][0]['width'];
                    tube_data[i]["thumb_height"] = feed_item['media$group']['media$thumbnail'][0]['height'];
                    tube_data[i]["thumb_url"] = feed_item['media$group']['media$player'][0]['url']
                    var vid_1 = tube_data[i]["thumb_url"].search('v=');

                    var vid_2 = tube_data[i]["thumb_url"].search('&feature');

                    var vid_len = vid_2 - (vid_1 + 2);

                    tube_data[i]["vid"] = tube_data[i]["thumb_url"].substr(vid_1 + 2, vid_len);

                }

            });
   
        });

    }


This function is a bit more involved because it combines all the tags depending on the user choice. User can ask all the tags to be compulsory(and), any of the tags(or). The user might like a sub-set of new tags to be used from the original tag each time the program is executed.

var randomnumber = Math.floor(Math.random() * (tag_arr.length - 1)) + 1;
            qstring = tag_arr[randomnumber];

            for (k = 0; k <= randomnumber; k++) {
                randomnumber = Math.floor(Math.random() * tag_arr.length);
                qstring += "%7c" + tag_arr[randomnumber];

            }


The Lines above just choose a random number which signifies the number of tags to be considered and then inside a loop each time a new random number is generated to signify the tag chosen.


getPlayListVideos This function gets a playlist depending on the user-name and the playlist name. Unfortunately only those play list are available which have been marked public by the creator, if any play-list is marked as private it will not be available through this function.


this.getPlayListVideos = function(username, playlist, format) {

        var q = "http://gdata.youtube.com/feeds/api/users/" + username + "/playlists?alt=json-in-script";

        q += "&callback=?";

        $.getJSON(q, function(data) {





            $.each(data.feed.entry, function(i, item) {

                var title = item['title']['$t'];

                if (title.toLowerCase() == playlist.toLowerCase())

                    q = item['gd$feedLink'][0]['href'];





            });

            if (format == '5')

                q += "?alt=json-in-script&callback=?&format=5";

            else

                q += "?alt=json-in-script&callback=?&format=5";

            $.getJSON(q, function(json) {

                var htmlstr = '';



                tube_data = new Array(json.feed.entry.length);

                $.each(json.feed.entry, function(i, pl_item) {

                    var title2 = pl_item['media$group']['media$title']['$t'];



                    tube_data[i] = new Array(6)

                    if (pl_item['app$control'] != undefined && pl_item['app$control']['yt$state'] != undefined) {

                        var thumb = pl_item['app$control']['yt$state']['$t'];

                        var url = '#';

                        tube_data[i]["thumb_url"] = '#';

                        tube_data[i]["vid"] = pl_item['app$control']['yt$state']['$t'];

                    }



                    else {

                        tube_data[i]["thumb_title"] = pl_item['title']['$t'];

                        tube_data[i]["thumb_img"] = pl_item['media$group']['media$thumbnail'][0]['url'];

                        tube_data[i]["thumb_width"] = pl_item['media$group']['media$thumbnail'][0]['width'];

                        tube_data[i]["thumb_height"] = pl_item['media$group']['media$thumbnail'][0]['height'];

                        tube_data[i]["thumb_url"] = pl_item['media$group']['media$player'][0]['url']

                        var vid_1 = tube_data[i]["thumb_url"].search('v=');

                        var vid_2 = tube_data[i]["thumb_url"].search('&feature');

                        var vid_len = vid_2 - (vid_1 + 2);

                        tube_data[i]["vid"] = tube_data[i]["thumb_url"].substr(vid_1 + 2, vid_len);

                    }





                });

            });

    });



    }


This function has two getJSON calls why because, the first call brings all the playlist of the user specified. Then the url for the playlist specified is parsed from the first feed result. After this we get the actual request URL for the playlist. this url is used to fire the second request.
The second request brings the videos and their data.
As mentioned earlier, I have not shown you how to use the parsed data because that is another post may be later in the week. I will put up a test page and a you tube video for the full code very soon. Please subscribe to my feed for further updates. If you want to watch a real-life example please click here or visit http://coolnerdblogger.com/mydownloads/YoutubeSlide/jQueryAndYouTube.html


1 comment:

  1. I need don´t show the word "VID" and its code word, I need to make it hidden, can you help me, please!

    ReplyDelete

 
EatonWeb Blog Directory