Thursday, 20 May 2010

Getting Started with YouTube Java API


In this tutorial I am taking a look at Google's YouTube API which allows you to empower your application with YouTube's features. YouTube is one of the “killer” Internet applications and its traffic comprises of a huge portion of the total internet traffic.

Before we get started, make sure you have read the API Overview Guide. We will mainly deal with the Data API, which allows you to perform many of the operations available on the YouTube website (search for videos, retrieve standard feeds, see related content etc.).

The API is available in multiple programming languages and we will be using Java for this tutorial. Read the Java Developer's Guide to get a first idea. Also bookmark the Google Data API JavaDoc page.

Let's prepare the development environment. First, download the GData Java Client from the corresponding download section. I will be using the 1.41.2 version for this tutorial. Note that there is also a version 2, but according to the site is experimental and not compatible with version 1.

Extract the zipped file, locate the folder “gdata\java\lib” and include the following JARs into your application's classpath:
  • data-client-1.0.jar
  • gdata-youtube-2.0.jar
  • gdata-core-1.0.jar
  • gdata-media-1.0.jar
Next, we have to take care of the dependencies. The list of dependency packages can be found here.
Make sure all the aforementioned JAR files are included in the project's classpath.



Note that all public feeds are read-only and do not require any authentication. Authenticated operations, on the other hand, are those that include the retrieval of private feeds, such as a user's inbox feed, as well as write, upload, update and delete operations. You will need to sign up for a developer key to be able to execute authenticated operations. No key is required for this tutorial though.

Now that the infrastructure is ready, let's talk a bit about the API. The main class that we will be using is the YouTubeService class. This allows you to perform search queries similar to the ones that you can perform while browsing YouTube's web page. Each query is represented by a YouTubeQuery instance. The results of each query (if any), come in the form of a VideoFeed object.

From each feed, a number of VideoEntry objects can be retrieved. From a VideoEntry, we extract a YoutTubeMediaGroup object. You can imagine this class as a placeholder for media information (check the "Media RSS" Specification). We then retrieve the corresponding MediaPlayer and finally the player URL. We can also get information about the accompanying thumbnails, via the MediaThumbnail class.

Let's get started with the code. First we create two model classes which will be used to hold information about the feeds and the videos. The first one is called YouTubeMedia and contains the media content URL and the media content type. The second one is named YouTubeVideo and contains all the information regarding a specific video (URL, embedded player URL, thumbnails and instances of YoutTubeMedia). The source code for these is following:
package com.javacodegeeks.youtube.model;

public class YouTubeMedia {
 
     private String location;
     private String type;
 
     public YouTubeMedia(String location, String type) {
          super();
          this.location = location;
          this.type = type;
     }
 
     public String getLocation() {
          return location;
     }
     public void setLocation(String location) {
          this.location = location;
     }
 
     public String getType() {
          return type;
     }
     public void setType(String type) {
          this.type = type;
     } 
 
}
package com.javacodegeeks.youtube.model;

import java.util.List;

public class YouTubeVideo {
 
     private List<String> thumbnails;
     private List<YouTubeMedia> medias;
     private String webPlayerUrl;
     private String embeddedWebPlayerUrl;
 
     public List<String> getThumbnails() {
          return thumbnails;
     }
     public void setThumbnails(List<String> thumbnails) {
          this.thumbnails = thumbnails;
     }

     public List<YouTubeMedia> getMedias() {
          return medias;
     }
     public void setMedias(List<YouTubeMedia> medias) {
         this.medias = medias;
     }
 
     public String getWebPlayerUrl() {
          return webPlayerUrl;
     }
     public void setWebPlayerUrl(String webPlayerUrl) {
            this.webPlayerUrl = webPlayerUrl;
     }

     public String getEmbeddedWebPlayerUrl() {
          return embeddedWebPlayerUrl;
     }
     public void setEmbeddedWebPlayerUrl(String embeddedWebPlayerUrl) {
          this.embeddedWebPlayerUrl = embeddedWebPlayerUrl;
     }
 
     public String retrieveHttpLocation() {
          if (medias==null || medias.isEmpty()) {
               return null;
          }
          for (YouTubeMedia media : medias) {
               String location = media.getLocation();
               if (location.startsWith("http")) {
                    return location;
               }
          }
          return null;
      }

}

Finally, the YouTubeManager class is presented. It can be used to perform search queries and returns instances of the YouTubeVideo model class with all the relevant information. It also creates the appropriate embedded web player URL. Here is the code for that class:

package com.javacodegeeks.youtube;

import java.net.URL;
import java.util.LinkedList;
import java.util.List;

import com.google.gdata.client.youtube.YouTubeQuery;
import com.google.gdata.client.youtube.YouTubeService;
import com.google.gdata.data.media.mediarss.MediaThumbnail;
import com.google.gdata.data.youtube.VideoEntry;
import com.google.gdata.data.youtube.VideoFeed;
import com.google.gdata.data.youtube.YouTubeMediaContent;
import com.google.gdata.data.youtube.YouTubeMediaGroup;
import com.javacodegeeks.youtube.model.YouTubeMedia;
import com.javacodegeeks.youtube.model.YouTubeVideo;

public class YouTubeManager {
 
    private static final String YOUTUBE_URL = "http://gdata.youtube.com/feeds/api/videos";
    private static final String YOUTUBE_EMBEDDED_URL = "http://www.youtube.com/v/";
 
    private String clientID;
 
    public YouTubeManager(String clientID) {
        this.clientID = clientID;
    }
 
     public List<YouTubeVideo> retrieveVideos(String textQuery, int maxResults, boolean filter, int timeout) throws Exception {
  
        YouTubeService service = new YouTubeService(clientID);
        service.setConnectTimeout(timeout); // millis
        YouTubeQuery query = new YouTubeQuery(new URL(YOUTUBE_URL));
  
        query.setOrderBy(YouTubeQuery.OrderBy.VIEW_COUNT);
        query.setFullTextQuery(textQuery);
        query.setSafeSearch(YouTubeQuery.SafeSearch.NONE);
        query.setMaxResults(maxResults);

        VideoFeed videoFeed = service.query(query, VideoFeed.class);  
        List<VideoEntry> videos = videoFeed.getEntries();
  
        return convertVideos(videos);
  
    }
 
    private List<YouTubeVideo> convertVideos(List<VideoEntry> videos) {
  
        List<YouTubeVideo> youtubeVideosList = new LinkedList<YouTubeVideo>();
  
        for (VideoEntry videoEntry : videos) {
   
            YouTubeVideo ytv = new YouTubeVideo();
   
            YouTubeMediaGroup mediaGroup = videoEntry.getMediaGroup();
            String webPlayerUrl = mediaGroup.getPlayer().getUrl();
            ytv.setWebPlayerUrl(webPlayerUrl);
   
            String query = "?v=";
            int index = webPlayerUrl.indexOf(query);

            String embeddedWebPlayerUrl = webPlayerUrl.substring(index+query.length());
            embeddedWebPlayerUrl = YOUTUBE_EMBEDDED_URL + embeddedWebPlayerUrl;
            ytv.setEmbeddedWebPlayerUrl(embeddedWebPlayerUrl);
   
            List<String> thumbnails = new LinkedList<String>();
            for (MediaThumbnail mediaThumbnail : mediaGroup.getThumbnails()) {
                thumbnails.add(mediaThumbnail.getUrl());
            }   
            ytv.setThumbnails(thumbnails);
   
            List<YouTubeMedia> medias = new LinkedList<YouTubeMedia>();
            for (YouTubeMediaContent mediaContent : mediaGroup.getYouTubeContents()) {
                medias.add(new YouTubeMedia(mediaContent.getUrl(), mediaContent.getType()));
            }
            ytv.setMedias(medias);
   
            youtubeVideosList.add(ytv);
   
        }
  
        return youtubeVideosList;
  
    }
 
}

In order to test our class, as well provide a show case example, we create the following simple test class:
package com.javacodegeeks.youtube.test;

import java.util.List;

import com.javacodegeeks.youtube.YouTubeManager;
import com.javacodegeeks.youtube.model.YouTubeVideo;

public class YouTubeTester {
 
    public static void main(String[] args) throws Exception {
  
        String clientID = "JavaCodeGeeks";
        String textQuery = "java code";
        int maxResults = 10;
        boolean filter = true;
        int timeout = 2000;
  
        YouTubeManager ym = new YouTubeManager(clientID);
  
        List<YouTubeVideo> videos = ym.retrieveVideos(textQuery, maxResults, filter, timeout);
  
        for (YouTubeVideo youtubeVideo : videos) {
            System.out.println(youtubeVideo.getWebPlayerUrl());
            System.out.println("Thumbnails");
            for (String thumbnail : youtubeVideo.getThumbnails()) {
                System.out.println("\t" + thumbnail);
            }
            System.out.println(youtubeVideo.getEmbeddedWebPlayerUrl());
            System.out.println("************************************");
        }
  
    }

}

The Eclipse project for this tutorial, including the dependency libraries, can be downloaded here.

Enjoy!

Related Articles :



20 comments:

  1. I am getting this :

    Exception in thread "main" java.net.SocketException: Connection reset by peer: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:525)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:158)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
    at sun.net.www.http.HttpClient.(HttpClient.java:233)
    at sun.net.www.http.HttpClient.New(HttpClient.java:306)
    at sun.net.www.http.HttpClient.New(HttpClient.java:323)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:860)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:801)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:726)
    at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:503)

    I guess it has something to do with firewall or proxy.

    ReplyDelete
  2. Hi Mike,

    I believe that this error message means that the remote peer (YouTube server) accepted the request, but for some reason closed the connection unexpectedly. So, most probably it really is a connectivity problem.

    Are you running the example using the provided Eclipse project?

    ReplyDelete
  3. Hi Fabrizio
    Great article, and thanks for posting it on JavaLobby. When you get a chance can you send me a mail to james at dzone.com. Thanks

    Regards
    James

    ReplyDelete
  4. Even i am getting the same error

    Exception in thread "main" java.net.SocketTimeoutException: connect timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:519)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:158)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
    at sun.net.www.http.HttpClient.(HttpClient.java:233)
    at sun.net.www.http.HttpClient.New(HttpClient.java:306)
    at sun.net.www.http.HttpClient.New(HttpClient.java:323)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:852)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:793)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:718)
    at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:503)
    at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:535)
    at com.google.gdata.client.Service.getFeed(Service.java:1135)
    at com.google.gdata.client.Service.getFeed(Service.java:1077)
    at com.google.gdata.client.GoogleService.getFeed(GoogleService.java:662)
    at com.google.gdata.client.Service.query(Service.java:1237)
    at com.google.gdata.client.Service.query(Service.java:1178)
    at com.javacodegeeks.youtube.YouTubeManager.retrieveVideos(YouTubeManager.java:40)
    at com.javacodegeeks.youtube.test.YouTubeTester.main(YouTubeTester.java:20)

    Can i what needs to change, I imported this project to my eclipse

    ReplyDelete
  5. This is a really great and fun topic
    I'm gonna give this a try after downloading the eclipse project
    http://abuyaseen.blogspot.com/

    ReplyDelete
  6. Thanks a lot for the great effort. I wonder if we can retrieve the tags associated with the videos. I need this metadata in my thesis. You help will be highly appreciated.

    ReplyDelete
  7. hi thank for your help
    this will print the urls
    then how can i show those videos as thumnails in the htmlpage
    please help me

    thanks

    ReplyDelete
  8. Even i am getting the same error. I followed the steps from this article.

    Exception in thread "main" java.net.SocketTimeoutException: connect timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:519)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:158)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
    at sun.net.www.http.HttpClient.(HttpClient.java:233)
    at sun.net.www.http.HttpClient.New(HttpClient.java:306)
    at sun.net.www.http.HttpClient.New(HttpClient.java:323)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:852)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:793)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:718)
    at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:503)
    at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:535)
    at com.google.gdata.client.Service.getFeed(Service.java:1135)
    at com.google.gdata.client.Service.getFeed(Service.java:1077)
    at com.google.gdata.client.GoogleService.getFeed(GoogleService.java:662)
    at com.google.gdata.client.Service.query(Service.java:1237)
    at com.google.gdata.client.Service.query(Service.java:1178)
    at com.javacodegeeks.youtube.YouTubeManager.retrieveVideos(YouTubeManager.java:40)
    at com.javacodegeeks.youtube.test.YouTubeTester.main(YouTubeTester.java:20)

    Can anyone help me resolving this?

    ReplyDelete
  9. Hi:Socket connection error may be solved by add internet access permission in Manifest.xml file.

    ReplyDelete
  10. Hello,

    I downloaded it, and compiled it successfully. However, when it is run, the program is just stuck, never completed. what is wrong? Thanks

    ReplyDelete
  11. Hi tao,

    What do you mean by "is just stuck"? Do you get any of the System.out prints on your console? Or do you get an exception? Perhaps you are facing a time-out error. Make sure you have an internet connection when trying this tutorial.

    Regards,
    Fabrizio

    ReplyDelete
  12. No error, no exception. It seems waiting on the following call forever
    VideoFeed videoFeed = service.query(query, VideoFeed.class);

    My Internet connection is ok. I can search video on YouTube directly

    ReplyDelete
  13. Hi tao,
    I am lost. I have no idea what could cause this. Let me ask, have you tried to run the application by using directly the provided Eclipse project?

    ReplyDelete
  14. Same as Tao is getting ...No error, no exception. It seems waiting on the following call forever
    VideoFeed videoFeed = service.query(query, VideoFeed.class);

    My Internet connection is ok. I can search video on YouTube directly.

    Can anyone please help me to get rid off.

    ReplyDelete
  15. Hey guys,

    It seems that the application has been broken since I first wrote this tutorial back in May.

    I will try to revisit it during the weekend and see what is wrong with it.

    ReplyDelete
  16. Hey guys,

    I just checked the sample application by importing the project. It works fine, no problems encountered.

    A thing to notice is that in this line

    VideoFeed videoFeed = service.query(query, VideoFeed.class);

    the Youtube API client performs an HTTP request. Thus, most of your problems will be caused by networking issues. Please check all aspects of your network configuration (e.g. a proxy might be required).

    Regards,
    Fabrizio

    ReplyDelete
  17. Exception in thread "main" java.net.UnknownHostException: gdata.youtube.com
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:177)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:529)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:158)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
    at sun.net.www.http.HttpClient.(HttpClient.java:233)
    at sun.net.www.http.HttpClient.New(HttpClient.java:306)
    at sun.net.www.http.HttpClient.New(HttpClient.java:323)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:860)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:801)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:726)
    at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:503)
    at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:535)
    at com.google.gdata.client.Service.getFeed(Service.java:1135)
    at com.google.gdata.client.Service.getFeed(Service.java:1077)
    at com.google.gdata.client.GoogleService.getFeed(GoogleService.java:662)
    at com.google.gdata.client.Service.query(Service.java:1237)
    at com.google.gdata.client.Service.query(Service.java:1178)
    at YouTubeManager.retrieveVideos(YouTubeManager.java:40)
    at YouTubeTester.main(YouTubeTester.java:21)


    now i dont know how to proceed can u explain step by step after this....

    ReplyDelete
  18. awesome tutorial, loved it

    ReplyDelete
  19. Is possible to send video from my site to youtube? Something like a FORM into may site, that user get a video and send to youtube? Thanks...

    ReplyDelete

Related Posts Plugin for WordPress, Blogger...