My favorites | English | Sign in

Sign up for Google I/O 2010 today!

YouTube APIs and Tools

YouTube logo

Developer's Guide: PHP

The YouTube Data API allows client applications to retrieve and update YouTube content in the form of Google Data API feeds. Your client application can use the YouTube Data API to fetch video feeds, comments, responses, and playlists, as well as query for videos that match particular criteria. You can also use the API to make authenticated requests to modify this information and to upload new video content to the site.

In addition to providing some background on the capabilities of the YouTube Data API, this document provides examples for interacting with the API using the PHP client library. You can download the client library as a standalone release (distributed by Zend) or as part of the Zend Framework. If you need help setting up the PHP client library, the Getting Started Guide is the place to look. If you're interested in understanding more about the underlying protocol used by the PHP client library to interact with YouTube, see the Developer's Guide protocol.

The PHP Client Library is by no means the only way to use the YouTube Data API with PHP. There are other great resources out there, such as this developerWorks article detailing how to use the API with SimpleXML.

Contents

About this document

Audience

This document is intended for programmers who want to write client applications that can interact with YouTube using the PHP client library. It provides a series of examples of basic data API interactions.

For YouTube Data API reference information, including expected latencies for data updates, please see the reference guide.

This document assumes that you understand the general ideas behind the Google Data APIs protocol, and that you know PHP.

For reference information about the PHP classes and methods, see the client library's API guide.

Document structure

This document contains the following sections:

  • The Authentication section describes the two different authentication methods available for associating API operations with a specific user account. This section also outlines the differences between authentication for the YouTube Data API and other Google Data APIs. Throughout this document, the explanations of specific API functions will clearly indicate whether the function requires user authentication. In general, all requests that modify video or feed data need to be authenticated. Read-only requests to retrieve public videos do not require authentication.

  • The Understanding video feeds and entries section provides a sample API response and explains how to extract information about a single video from a list of videos or a set of search results. This section also explains how to access metadata about a specific video entry.

  • The Retrieving and searching for videos section explains how to fetch a list of videos. The YouTube Data API defines several types of standard feeds, such as top-rated or most-viewed videos. This section explains how also to retrieve a list of videos uploaded by a specific user or a list of related videos. Finally, this section explains how to use the API to let users search through YouTube's video library for videos matching specific search terms or categories.

  • The Uploading videos section briefly explains two ways that you can allow users to upload videos to YouTube from your application. This section also explains how to let users delete videos from your application. These solutions are explained in more detail in the Protocol Guide. You may need to let users upload videos to use certain other API functions. For example, the API provides a function for adding a video response to a video. If the user is uploading a new video as a video response, then your client will need to follow the video uploading instructions to add the video to YouTube before identifying the new video as a response.

  • The Updating and deleting videos section describes how to use the API to update information about a YouTube video. It also describes how a video can be removed using the API.

  • The Using community features section describes API functions that allow your users to interact with YouTube videos. These functions explain requests for posting a rating, comment, video response or complaint to an existing video. You can also use the API to retrieve lists of video comments or video responses or to delete a video response.

  • The Saving and collecting videos section explains how to use the API to access, create and update favorite videos, video playlists and subscriptions to YouTube channels. It also explains how to modify video playlists and favorites by adding and removing videos.

  • The Enabling user interaction section explains how to use the API to retrieve and update user profiles. This section also explains how to retrieve, add, update and delete user contacts as well as how to retrieve, send and delete messages.

Getting Started

To use the PHP client library, you must be running PHP >= 5.1.4. You also need to use Zend_Gdata >= 1.7.7, which is distributed as part of the Zend Framework. See the Getting Started Guide for more information about configuring your environment.

The snippets of sample code in this document can be copied and pasted into your code and then modified to fit the needs of your application. In addition, the client library is distributed with a sample application that demonstrates many API operations. The code is located in the /demos/YouTubeVideoApp folder.

Before you can perform any operations with the YouTube Data API, you must initialize a Zend_Gdata_YouTube object as shown in the following example. (Most of the method examples in this guide also operate on an instance of Zend_Gdata_YouTube.) Please note that all API operations that do not involve retrieving public content will require authentication.

<?php
require_once 'Zend/Loader.php'; // the Zend dir must be in your include_path
Zend_Loader::loadClass('Zend_Gdata_YouTube');
$yt = new Zend_Gdata_YouTube();

To use API functionality that requires user authentication, you will also need to include the one of the following helper classes, depending on whether you plan to use AuthSub or ClientLogin authentication.

Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); 

Note: The contents of the Zend library directory must be in your PHP include_path.

Authentication

The PHP client library can be used to retrieve public feeds or to execute authenticated operations. All public feeds are read-only and do not require any authentication. Authenticated operations, on the other hand, 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.

You can authenticate requests using either AuthSub proxy authentication or ClientLogin username/password authentication.

Please see the Protocol Guide and the authentication documentation for Google Data APIs for more information about AuthSub and ClientLogin.

AuthSub for web applications

AuthSub proxy authentication enables web applications to authenticate users to their YouTube accounts without having to access the user's YouTube username and password. You should use AuthSub authentication if you are building a web application that will let users link videos, comments, ratings, contacts or other information to their own YouTube accounts.

When a user visits your application for the first time, the user will not yet have been authenticated to use your application to access Google services. To authenticate the user, you need to display a link that points the user to a Google login page. After the user logs in, she can authorize your application to use the API to access her account. Google will then redirect the user back to a URL specified in your authentication request. The redirect will include a single-use token that your application can use to execute an API operation.

The following sample code constructs an AuthSub request URL. The code retrieves a nonsecure token that will be exchanged for a session token, which can then be used multiple times.

// start a new session 
session_start();

function getAuthSubRequestUrl()
{
    $next = 'http://www.example.com/welcome.php';
    $scope = 'http://gdata.youtube.com';
    $secure = false;
    $session = true;
    return Zend_Gdata_AuthSub::getAuthSubTokenUri($next, $scope, $secure, $session);
}

You pass the following parameters to the getAuthSubRequestUrl method:

  • The $next parameter contains the URL to which the user will be redirected after logging in to YouTube.

  • The $scope parameter identifies the service that the user is enabling your site to access on his behalf. The value of this parameter must be http://gdata.youtube.com.

  • The $secure parameter contains a boolean value (0 or 1) that indicates whether the authentication service will return a secure or nonsecure token. Secure tokens are issued only to websites that have registered with Google, and video upload requests that use a secure token must be digitally signed. Please see the Google AuthSub documentation for more details about secure tokens.

  • The $session parameter contains a boolean value (0 or 1) that indicates whether the single-use authentication token that the authentication service returns can be exchanged for a session token, which can be used multiple times. Set this variable to 1 to indicate that the single-use token can be exchanged for a session token. Please see the Google AuthSub documentation for an explanation of how to request a session token.

The AuthSub request URL will have the following format. (Your request URLs may specify different parameter values.)

https://www.google.com/accounts/AuthSubRequest?
  next=http%3A%2F%2Fwww.example.com%2Fwelcome.php
  &scope=http%3A%2F%2Fgdata.youtube.com
  &session=1
  &secure=0

After the user logs in via YouTube's authentication service, YouTube will redirect the user back to the URL identified in the next parameter in your AuthSub request. The redirect contains a single-use authentication token, which is identified by the token parameter in the URL as shown. If the value of the session parameter in your AuthSub request was 1, then you can exchange the single-use token for a session token by submitting a getAuthSubSessionToken request. The following URL shows how the token parameter will appear in the redirect to your site.

http://www.example.com/welcome?token=DQAADKEDE

Your application can set an authentication cookie before the user has the opportunity to link to the AuthSub request URL. The cookie can then enable your application to recognize the authenticated user after the AuthSub authentication page redirects the user to your web page.

Upgrading to a session token

As noted above, the token that you receive in the redirect URL is a single-use token. You can exchange the single-use token for a session token, which does not expire, by submitting a getAuthSubSessionToken request. The function below demonstrates how to make this exchange. If no session token has been set, but a single-use token exists, the function exchanges the single-use token for a session token. If no single-use token exists and no session token exists, the function builds an authentication URL using the getAuthSubRequestUrl function described earlier.

function getAuthSubHttpClient()
{
    if (!isset($_SESSION['sessionToken']) && !isset($_GET['token']) ){
        echo '<a href="' . getAuthSubRequestUrl() . '">Login!</a>';
        return;
    } else if (!isset($_SESSION['sessionToken']) && isset($_GET['token'])) {
      $_SESSION['sessionToken'] = Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
    }

    $httpClient = Zend_Gdata_AuthSub::getHttpClient($_SESSION['sessionToken']);
    return $httpClient;
}

You can create a fully authenticated YouTube service object by passing the $httpClient object to the Zend_Gdata_YouTube service object's constructor. You will also need to pass an ID for your application, your YouTube developer key and your client ID to the constructor. The developer key is only necessary if your application lets users upload videos, perform API write operations such as creating playlists or adding comments, or retrieve private feeds, such as a user's inbox feed. The application ID and the client ID identify your application for logging and debugging purposes.

$yt = new Zend_Gdata_YouTube($httpClient, $applicationId, $clientId, $developerKey);

You can then use the fully authenticated service object to perform all further YouTube API requests. An AuthSub session token will not expire unless you specifically issue a request to revoke it. For example, your application could obtain a token at the beginning of a user's session and then revoke the token at the end of the session. A user can also revoke access to your application (and its associated token) through the Authorized Sites page in the user's YouTube account.

ClientLogin for installed applications

ClientLogin authentication is used in installed applications that store the user's email address (username) and password. To use ClientLogin authentication, call the static getHttpClient method of the Zend_Gdata_ClientLogin class, specifying the email and password of the user associated with the authentication request. Please note that your authentication request must also pass the authentication URL specified in the sample code.

Note: ClientLogin authentication should not be used in Web applications, which should use AuthSub authentication instead.

The following code demonstrates how to use ClientLogin to authenticate a user.

$authenticationURL= 'https://www.google.com/youtube/accounts/ClientLogin';
$httpClient = 
  Zend_Gdata_ClientLogin::getHttpClient(
              $username = 'myuser@gmail.com',
              $password = 'mypassword',
              $service = 'youtube',
              $client = null,
              $source = 'MySource', // a short string identifying your application
              $loginToken = null,
              $loginCaptcha = null,
              $authenticationURL);

Once the credentials have been set, the $httpClient object can be used to handle all further requests to the Zend_Gdata_YouTube service. To be able to perform uploads and any kind of write operations, such as adding comments or creating playlists, you also need to provide your developer key and client ID when you initialize the Zend_Gdata_YouTube object. Please visit http://code.google.com/apis/youtube/dashboard to obtain a developer key and client ID.

$developerKey = 'ABC123 ... ';
$applicationId = 'Video uploader v1';
$clientId = 'My video upload client - v1';

$yt = new Zend_Gdata_YouTube($httpClient, $applicationId, $clientId, $developerKey);

Please refer to the developer's guide for more detailed information about the AuthSub and ClientLogin mechanisms.

Setting the API version

As of version 1.7.4 of the PHP Client Library, the version 2 specific functionality has not yet been enabled by default. You can use the setMajorProtocolVersion function to set a version for either a service class, a feed or an entry. A version 2 specific service class will always return v2 feeds and entries.

// Assuming that $yt is a valid Zend_Gdata_YouTube object
$yt->setMajorProtocolVersion(2);

This guide will assume that all instances of the Zend_Gdata_YouTube service object (denoted as $yt) are version 2 objects.

Note: The client library may be modified in the future so that version 2 is enabled by default.

Understanding video feeds and entries

The YouTube Data API provides several video feeds that represent lists of videos, such as standard feeds, uploads, subscriptions, and favorite videos. The URL for each feed is documented in the reference guide.

Displaying a feed of videos

Many feeds in the YouTube API consist of video entries. These feeds can be modeled most simply as Zend_Gdata_YouTube_VideoFeed (VideoFeed) objects, each of which contains a number of Zend_Gdata_YouTube_VideoEntry (VideoEntry) objects. Each video entry corresponds to exactly one YouTube video and contains information about that video.

The following code retrieves a video feed and then prints information about each entry in the feed:

function getAndPrintVideoFeed($location = Zend_Gdata_YouTube::VIDEO_URI)
{
  $yt = new Zend_Gdata_YouTube();
  // set the version to 2 to receive a version 2 feed of entries
  $yt->setMajorProtocolVersion(2);
  $videoFeed = $yt->getVideoFeed($location);
  printVideoFeed($videoFeed);
}
 
function printVideoFeed($videoFeed)
{
  $count = 1;
  foreach ($videoFeed as $videoEntry) {
    echo "Entry # " . $count . "\n";
    printVideoEntry($videoEntry);
    echo "\n";
    $count++;
  }
}

The Retrieving and searching for videos section describes different types of video feeds and provides the URLs and instructions for retrieving those feeds.

Retrieving a specific video entry

Each entry in a video feed contains a link element for which the rel attribute value is self. This tag identifies the URL for a feed of information about that particular video. The URL has the following format:

http://gdata.youtube.com/feeds/api/videos/videoID

The following code retrieves a VideoEntry object, which corresponds to a particular YouTube video, and then prints the metadata for the video:

$videoEntry = $yt->getVideoEntry('the0KZLEacs');
printVideoEntry($videoEntry);

Video entry contents

A VideoEntry object, which corresponds to an entry in an Atom feed, contains many different pieces of metadata about a video, ranging from video player URLs to thumbnail images to details like the video's duration and keywords.

The following code demonstrates how to print a variety of details about a video. Many important data fields for a VideoEntry object are specified by the children of the <media:group> element. In the PHP client library, that element is mapped to the Zend_Gdata_YouTube_Extension_MediaGroup (MediaGroup) object, which can be retrieved by calling either $videoEntry->getMediaGroup() or $videoEntry->mediaGroup. The client library contains many help methods that facilitate easy access to the child elements of mediaGroup and that can be called directly from the VideoEntry object. For a complete list of all of the information that a VideoEntry object contains, please refer to the <entry> tag definition in the API Reference Guide. Specifically, refer to the <entry> tag's subtags for retrieving a video entry.

function printVideoEntry($videoEntry) 
{
  // the videoEntry object contains many helper functions
  // that access the underlying mediaGroup object
  echo 'Video: ' . $videoEntry->getVideoTitle() . "\n";
  echo 'Video ID: ' . $videoEntry->getVideoId() . "\n";
  echo 'Updated: ' . $videoEntry->getUpdated() . "\n";
  echo 'Description: ' . $videoEntry->getVideoDescription() . "\n";
  echo 'Category: ' . $videoEntry->getVideoCategory() . "\n";
  echo 'Tags: ' . implode(", ", $videoEntry->getVideoTags()) . "\n";
  echo 'Watch page: ' . $videoEntry->getVideoWatchPageUrl() . "\n";
  echo 'Flash Player Url: ' . $videoEntry->getFlashPlayerUrl() . "\n";
  echo 'Duration: ' . $videoEntry->getVideoDuration() . "\n";
  echo 'View count: ' . $videoEntry->getVideoViewCount() . "\n";
  echo 'Rating: ' . $videoEntry->getVideoRatingInfo() . "\n";
  echo 'Geo Location: ' . $videoEntry->getVideoGeoLocation() . "\n";
  echo 'Recorded on: ' . $videoEntry->getVideoRecorded() . "\n";
  
  // see the paragraph above this function for more information on the 
  // 'mediaGroup' object. in the following code, we use the mediaGroup
  // object directly to retrieve its 'Mobile RSTP link' child
  foreach ($videoEntry->mediaGroup->content as $content) {
    if ($content->type === "video/3gpp") {
      echo 'Mobile RTSP link: ' . $content->url . "\n";
    }
  }
  
  echo "Thumbnails:\n";
  $videoThumbnails = $videoEntry->getVideoThumbnails();

  foreach($videoThumbnails as $videoThumbnail) {
    echo $videoThumbnail['time'] . ' - ' . $videoThumbnail['url'];
    echo ' height=' . $videoThumbnail['height'];
    echo ' width=' . $videoThumbnail['width'] . "\n";
  }
}

Note: For more information about how to generate the information required to embed a video with a player in your page please refer to the protocol guide.

Determining whether a user can edit a video entry

By default, the getVideoEntry method will return a read-only video entry. If the user is authenticated and owns the video being retrieved, you can pass in true to the third parameter of the getVideoEntry method to retrieve an 'editable' video entry. You can also use the getFullVideoEntry method to retrieve editable video entries.

You can determine whether the currently authenticated user is the owner of a particular video entry by calling the getEditLink method on that entry. The sample code below demonstrates how to determine whether a video entry is editable.

if ($videoEntry->getEditLink() !== null) {
  echo "Video is editable by current user.\n";
}

Retrieving and searching for videos

Retrieving standard feeds

The YouTube Data API provides standard feeds selected based on a variety of criteria. Standard feeds are sitewide rather than user-specific. They contain lists of videos that either reflect YouTube user behavior, such as top-rated and most viewed video feeds, or were selected by YouTube staff, such as recently featured and mobile video feeds. Standard feeds are updated every few minutes.

The URLs for all standard feeds have the following format:

http://gdata.youtube.com/feeds/api/standardfeeds/FEED_IDENTIFIER

The following table lists the standard feeds available through the YouTube Data API.

Feed NameFeed Identifier
Most Viewedmost_viewed
Top Ratedtop_rated
Recently Featuredrecently_featured
Watch On Mobilewatch_on_mobile
Most Discussedmost_discussed
Top Favoritestop_favorites
Most Respondedmost_responded
Most Recentmost_recent

You can also retrieve region-specific standard feeds and category-specific standard feeds by specifying either a regionID, a category name, or both in the feed URL. The URL for a region- and category-specific standard feed has the following format:

http://gdata.youtube.com/feeds/api/standardfeeds/localeID/feedID_CATEGORY_NAME

For example, the following example shows the feed URL for a list of the top-rated comedies in Japan:

http://gdata.youtube.com/feeds/api/standardfeeds/JP/top_rated_Comedy

Please refer to the reference guide for more information about standard feeds, region-specific standard feeds and category-specific standard feeds.

The following example demonstrates how to retrieve a standard feed and print information about the videos in that feed. This example uses the YouTube::getVideoFeed() method. Note that the URLs for standard feeds may be defined constants and that some URLs may be retrieved using helper methods. You can also construct the URLs manually following the instructions above and in the reference guide. Note that your Zend_Gdata_YouTube service object does not need to be authenticated to retrieve standard feeds.

function getAndPrintStandardFeeds() 
{
  // constructing URL manually
  $YOUTUBE_GDATA_SERVER = 'http://gdata.youtube.com';
  $STANDARD_FEED_PREFIX = $YOUTUBE_GDATA_SERVER . '/feeds/api/standardfeeds/';
  $TOP_RATED_FEED = $STANDARD_FEED_PREFIX . 'top_rated';
  getAndPrintVideoFeed($TOP_RATED_FEED);

  // URL as a constant in Zend_Gdata_YouTube
  getAndPrintVideoFeed(Zend_Gdata_YouTube::STANDARD_TOP_RATED_URI);

  // using helper method
  $yt = new Zend_Gdata_YouTube();
  $yt->setMajorProtocolVersion(2);
  getAndPrintVideoFeed($yt->getRecentlyFeaturedVideoFeed());

  // choosing the time period for a standard feed
  $yt = new Zend_Gdata_YouTube();
  $yt->setMajorProtocolVersion(2);
  $query = $yt->newVideoQuery(Zend_Gdata_YouTube::STANDARD_TOP_RATED_URI);
  $query->setTime('today');
  getAndPrintVideoFeed($query);
}

Note: If you don't want to use the helper methods, you can also use version 2 specific constants such as STANDARD_TOP_RATED_URI_V2, STANDARD_MOST_VIEWED_URI_V2, STANDARD_RECENTLY_FEATURED_URI_V2, and STANDARD_WATCH_ON_MOBILE_URI_V2.

Videos uploaded by a specific user

For each YouTube user, the YouTube Data API defines a video feed that lists the videos that the user has uploaded. The video feed for a user's uploaded videos can be retrieved from the following URL:

http://gdata.youtube.com/feeds/api/users/username/uploads

The following code demonstrates how to retrieve a feed of videos uploaded by a particular user:

function getAndPrintUserUploads($userName)                    
{     
  $yt = new Zend_Gdata_YouTube();
  $yt->setMajorProtocolVersion(2);
  printVideoFeed($yt->getuserUploads($userName));
}  

Note: In the feed URL, you can substitute the string default instead of a username to retrieve the videos uploaded by the currently authenticated user. In this case, you would retrieve the feed located at http://gdata.youtube.com/feeds/api/users/default/uploads.

Retrieving related videos

Each video entry in a video feed identifies the URL for another video feed that contains videos related to the entry, as determined by YouTube. To retrieve the related videos feed for a VideoEntry object, pass the video id of the VideoEntry object to the Zend_Gdata_YouTube object's getRelatedVideoFeed method. The following code shows how to retrieve and print information about the related videos for a particular VideoEntry.

$relatedVideosFeed = $yt->getRelatedVideoFeed($originalVideo->getVideoId());
foreach ($relatedVideosFeed as $relatedVideoEntry) {
  printVideoEntry($relatedVideoEntry);
}

Searching for videos

The YouTube Data API lets you request a set of videos that match a particular search term. The API supports a variety of standard Google Data query parameters and custom parameters specifically related to video search. For example, you can search for videos uploaded by a particular author or videos associated with a particular YouTube category.

To execute a search request, you will create a Zend_Gdata_YouTube_VideoQuery (VideoQuery) object that specifies your search criteria and pass that object to the YouTube::getVideoFeed method.

The following example demonstrates how to perform a search query for videos that match the search term "puppy". The query specifies that the result set may include restricted content and will be ordered by view count:

function searchAndPrint($searchTerms = 'puppy')
{
  $yt = new Zend_Gdata_YouTube();
  $yt->setMajorProtocolVersion(2);
  $query = $yt->newVideoQuery();
  $query->setOrderBy('viewCount');
  $query->setSafeSearch('none');
  $query->setVideoQuery($searchTerms);

  // Note that we need to pass the version number to the query URL function
  // to ensure backward compatibility with version 1 of the API.
  $videoFeed = $yt->getVideoFeed($query->getQueryUrl(2));
  printVideoFeed($videoFeed, 'Search results for: ' . $searchTerms);
}

In the client library code, the Zend_Gdata_Query (Query) class and subclasses like VideoQuery are responsible for constructing feed URLs. The example above constructs the following feed URL:

http://gdata.youtube.com/feeds/api/videos?q=keyword&safeSearch=none&orderby=viewCount

Note: To exclude a search term, prepend the term with a hyphen. (This functionality is also available in the search engine on the YouTube website.) For example, to search for videos matching the word 'dog' but not the word 'skateboarding', you would use the following code:

$query->setVideoQuery('dog -skateboarding');

The following list identifies some of the most common VideoQuery methods for setting search parameters. The reference guide contains a complete list of query parameters and their definitions. Since some of these parameters are not supported in version 1 of the YouTube Data API, you must specify a version in your YouTube service class to automatically set the appropriate header for your API requests.

setAuthor
The setAuthor method sets the author of the entry.
setFormat
The setFormat method specifies a video format or a set of video formats.
setLocation
The setLocation method specifies geographic coordinates (latitude, longitude) for a specific location.
setLocationRadius
The setLocationRadius method, in conjunction with the setLocation method, defines a geographic area. Search results will include videos associated with locations in that area.
setMaxResults
The setMaxResults method sets the maximum number of entries to return at one time.
setOrderBy
The setOrderBy method sets the order in which to list entries, such as by RELEVANCE, VIEW_COUNT, UPDATED, or RATING.
setSafeSearch
The setSafeSearch method indicates amount of filtering (none, moderate or strict) that YouTube should apply to remove restricted content from search results.
setStartIndex
The setStartIndex method sets the 1-based index of the first result to be retrieved (for paging).
setTime
The setTime method sets a time period to limit standard feed results to: TODAY, THIS_WEEK, THIS_MONTH, or ALL_TIME.
setUploader
The setUploader method restricts search results to videos from YouTube Partner Program participants. The only value that this method accepts is partner.
setVideoQuery
The setVideoQuery method sets a search query term. The API will search for the specified string in all video metadata, such as titles, tags, and descriptions.

Note: To set a parameter value if the parameter does not have a corresponding helper method in the VideoQuery class, call the $query->setParam('name', 'value') method.

Searching for videos using categories and keywords

You can restrict search results to show only videos that match a given set of categories and/or keywords. The reference guide describes how to specify both predefined YouTube categories, such as "Comedy" or "Music", and user-defined keywords, which are also known as tags. Each video can have many keywords but can only be associated with one YouTube category.

Key point: Some words, such as "comedy", can be both a YouTube category and a keyword. To distinguish between categories and keywords, the API uses the convention that capitalized words (e.g. "Comedy") denote YouTube categories and lowercase words (e.g. "comedy") denote keywords.

The following code demonstrates how to search for videos in the "News" category that match the keywords "sports" and "football". The example shows how to filter search results using both categories and keywords.

function searchAndPrintVideosByKeywords($searchTermsArray)
{
  $yt = new Zend_Gdata_YouTube(); 
  $query = $yt->newVideoQuery();
  $query->setOrderBy('viewCount');
  $query->setRacy('include');
  $query->setCategory('News/sports/football');

  /*
   * The following commented-out code block demonstrates how to generate 
   * the value that is passed to $query->setCategory
   * 
   * $keywordQuery = '';
   * foreach ($searchTermsArray as $searchTerm) {
   *   $keywordQuery .= strtolower($searchTerm) . '/';
   * }
   * $query->setCategory($keywordQuery);
   */

  $videoFeed = $yt->getVideoFeed($query);
  printVideoFeed($videoFeed, 'Search results for keyword search:');
}

The previous example retrieved videos that matched the "News" category and the keywords "sports" and "football". The following example, on the other hand, retrieves videos that match the "News" category and either or both of those keywords. Note that to specify that a video must match the keyword "sports" or the keyword "football", instead of separating those two terms with a forward slash ("/") in the value passed to the $query->setCategory() function, you would separate them with %7C, which is a URL-escaped pipe character.

function searchAndPrintVideosByKeywords($searchTermsArray)
{
  $yt = new Zend_Gdata_YouTube(); 
  $query = $yt->newVideoQuery();
  $query->setOrderBy('viewCount');
  $query->setRacy('include');
  $query->setCategory('News/sports%7Cfootball');

  $videoFeed = $yt->getVideoFeed($query);
  printVideoFeed($videoFeed, 'Search results for keyword search:');
}

The reference guide explains how to retrieve a list of categories that can be used to classify YouTube videos. The guide also explains how to retrieve localized category lists for several languages and locales.

Searching for videos using developer tags

When a user uploads a video through your site or application, you can associate the video with developer tags that you use to identify the video. YouTube does not display developer tags to YouTube users; however, you can retrieve or update videos that match a specific developer tag.

Developer tags can only be associated with a video at the time that the video is uploaded. In addition, developer tags that are assigned when a video is uploaded cannot be altered thereafter.

Each developer tag that is associated with a video is linked to the developer key specified in the request to upload that video. To search for videos that match a particular developer tag, the search request must specify the same developer key as the original upload requests for those videos. This restriction ensures that information about videos associated with a particular developer tag is only available to the developer that assigned that tag. Search requests for videos matching a particular developer tag do not require user authentication.

The following code demonstrates how to retrieve a list of videos associated with a particular developer tag:

$devTagUrl =
  'http://gdata.youtube.com/feeds/api/videos/-/%7Bhttp%3A%2F%2Fgdata.youtube.com' .
  '%2Fschemas%2F2007%2Fdevelopertags.cat%7Dyour_tag_here';

// obtain a feed with videos matching the provided developer tag
$yt->getVideoFeed($devTagUrl);

Paging through results

API responses contain pagination links for the previous and/or next page of entries in a feed. The following code sample demonstrates how to retrieve the previous and next pages of results for a feed:

$videoFeed = $yt->getRecentlyFeaturedVideoFeed();

// See if the feed specifies a previous page of results.
// In this example, the following lines of code would throw an 
// exception since the $videoFeed contains the first page of results.
try {
  $previousFeed = $videoFeed->getPreviousFeed();
} catch (Zend_Gdata_App_Exception $e) {
  echo $e->getMessage() . "\n";
}

// See if the feed specifies a next page of results.
try {
  $nextFeed = $videoFeed->getNextFeed();
} catch (Zend_Gdata_App_Exception $e) {
  echo $e->getMessage() . "\n";
}

So, for example, you could use the following code to retrieve all results for a feed. This code performs the following operations:

  1. It retrieves a feed.
  2. It prints out all of the entries in the feed.
  3. It determines whether additional results for the feed are available.
    • If additional results are available, the code returns to step 1. (At this point, the feed being retrieved in step 1 is the next page of results.) The code repeats these steps until no additional results are available.

// Note tht this works on a v1 or v2 YouTube service object
$yt = new Zend_Gdata_YouTube();
$videoFeed = $yt->getUserUploads('GoogleDevelopers');

/**
 * Recursive function to print an entire feed.
 *
 * @param Zend_Gdata_YouTube_VideoFeed $videoFeed The feed to print
 *        in this iteration.
 * @param integer $counter The counter to display and increment
 *        on each printed feed entry.
 * @return void
 */
function printEntireFeed($videoFeed, $counter) {
 foreach($videoFeed as $videoEntry) {
   echo $counter . " - " . $videoEntry->getVideoTitle() . "\n";
   $counter++;
 }

 // See whether we have another set of results
 try {
   $videoFeed = $videoFeed->getNextFeed();
 } catch (Zend_Gdata_App_Exception $e) {
   echo $e->getMessage() . "\n";
   return;
 }

 if ($videoFeed) {
   echo "-- next set of results --\n";
   printEntireFeed($videoFeed, $counter);
 }
}

printEntireFeed($videoFeed, 1);

In an actual implementation, you might prefer to display pagination links rather than display all feed results on a single page. Since a feed could contain dozens or hundreds of results, pagination links might contribute to a more polished user interface.

If you do display pagination links, please be careful not to expose your developer credentials in those links. For example, if you use the client and key query parameters in API requests, then the pagination links in the API response will contain those values. As such, you would not want to expose those URLs directly through your user interface.

Uploading videos

You can upload videos in one of two ways:

  • Direct uploading allows you to add videos that are in your video library to YouTube. You should choose a direct-upload implementation if you want to host or store videos uploaded through your site and also add those videos to YouTube. In a direct-uploading scenario, when a user uploads a video through your site, the video will be sent to your servers. Your application will subsequently send an API request to upload the video from your server to YouTube.

  • Browser-based uploading allows you to accept video uploads from your users without having to handle, host or proxy the actual video files. You should choose a browser-based uploading process if you do not want to host or store the uploaded video files.

You must provide the following fields for all uploaded videos:

  • Title
  • Description
  • Category
  • Keywords

Note: Uploaded videos should be visible in the authenticated user's uploads feed immediately. In addition, a newly uploaded video will typically be included in search results a couple of hours after the upload completes. However, this delay may be longer during periods of heavy API server loads. Please see the Checking upload status section for more information.

Direct upload

To upload a video, you must construct a new VideoEntry object that contains metadata about the video. The following example shows how to upload the Quicktime video "file.mov" to YouTube with the following properties:

PropertyValue
TitleMy Test Movie
CategoryAutos
Keywordscars, funny
DescriptionMy description
Video private?false
Developer tagmydevtag, anotherdevtag
Video location37,-122 (lat,long)
Filenamefile.mov
File MIME typevideo/quicktime

The following code uploads the video:

// Note that this example creates an unversioned service object.
// You do not need to specify a version number to upload content
// since the upload behavior is the same for all API versions.
$yt = new Zend_Gdata_YouTube($httpClient);

// create a new VideoEntry object
$myVideoEntry = new Zend_Gdata_YouTube_VideoEntry();

// create a new Zend_Gdata_App_MediaFileSource object
$filesource = $yt->newMediaFileSource('file.mov');
$filesource->setContentType('video/quicktime');
// set slug header
$filesource->setSlug('file.mov');

// add the filesource to the video entry
$myVideoEntry->setMediaSource($filesource);

$myVideoEntry->setVideoTitle('My Test Movie');
$myVideoEntry->setVideoDescription('My Test Movie');
// The category must be a valid YouTube category!
$myVideoEntry->setVideoCategory('Autos');

// Set keywords. Please note that this must be a comma-separated string
// and that individual keywords cannot contain whitespace
$myVideoEntry->SetVideoTags('cars, funny');

// set some developer tags -- this is optional
// (see Searching by Developer Tags for more details)
$myVideoEntry->setVideoDeveloperTags(array('mydevtag', 'anotherdevtag'));

// set the video's location -- this is also optional
$yt->registerPackage('Zend_Gdata_Geo');
$yt->registerPackage('Zend_Gdata_Geo_Extension');
$where = $yt->newGeoRssWhere();
$position = $yt->newGmlPos('37.0 -122.0');
$where->point = $yt->newGmlPoint($position);
$myVideoEntry->setWhere($where);

// upload URI for the currently authenticated user
$uploadUrl = 'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads';

// try to upload the video, catching a Zend_Gdata_App_HttpException, 
// if available, or just a regular Zend_Gdata_App_Exception otherwise
try {
  $newEntry = $yt->insertEntry($myVideoEntry, $uploadUrl, 'Zend_Gdata_YouTube_VideoEntry');
} catch (Zend_Gdata_App_HttpException $httpException) {
  echo $httpException->getRawResponseBody();
} catch (Zend_Gdata_App_Exception $e) {
    echo $e->getMessage();
}

To upload videos as private, use the $myVideoEntry->setVideoPrivate(); method before starting the upload. You can also use the $videoEntry->isVideoPrivate() method to check whether a video entry is a private video.

Browser-based upload

Browser-based uploading follows almost the same process as direct uploading. However, there are a few key differences:

  • When you use direct uploading, your request specifies the location of the media file source. However, when you use browser-based uploading, the video is uploaded from the user's browser to YouTube and not directly from your server. As such, with browser-based uploading you do not attach a Zend_Gdata_App_MediaFileSource (MediaFileSource) object to the VideoEntry you are constructing.

  • Browser-based uploading uses a special URL instead of the authenticated user's uploads URL:

    http://gdata.youtube.com/action/GetUploadToken
  • When you use direct uploading, YouTube returns a VideoEntry for the uploaded video. However, when you use browser-based uploading, YouTube returns a URL and upload token that you will use to build a form through which the user completes the upload process.

The browser-based uploading process has several steps:

  1. You create a VideoEntry object that only contains metadata about the video being uploaded. The metadata includes all of the fields that you would specify in the direct uploading process – e.g. title, description, category, etc. – except the location of the actual video file.

  2. You pass the VideoEntry object as a parameter to the getFormUploadToken method.

  3. YouTube returns a URL and upload token that you then use to build a form through which the user uploads the video file associated with the metadata uploaded in the previous step. The following code sample completes steps 1 through 3 of this process:

    // Note that this example creates an unversioned service object.
    // You do not need to specify a version number to upload content
    // since the upload behavior is the same for all API versions.
    $yt = new Zend_Gdata_YouTube($httpClient);
    
    // create a new VideoEntry object
    $myVideoEntry = new Zend_Gdata_YouTube_VideoEntry();
    
    $myVideoEntry->setVideoTitle('My Test Movie');
    $myVideoEntry->setVideoDescription('My Test Movie');
    // The category must be a valid YouTube category!
    $myVideoEntry->setVideoCategory('Autos');
    
    // Set keywords. Please note that this must be a comma-separated string
    // and that individual keywords cannot contain whitespace
    $myVideoEntry->SetVideoTags('cars, funny');
    
    $tokenHandlerUrl = 'http://gdata.youtube.com/action/GetUploadToken';
    $tokenArray = $yt->getFormUploadToken($myVideoEntry, $tokenHandlerUrl);
    $tokenValue = $tokenArray['token'];
    $postUrl = $tokenArray['url'];
    
  4. You build a standard HTML form through which the user can upload the video file. The form must follow these guidelines:

    • It must use the upload URL, which was parsed from the API response in step 3, as the value of the <form> tag's action attribute.

    • You need to add the nexturl parameter to the form's target URL. This parameter specifies the URL to which YouTube will redirect the user's browser after the user uploads the video file.

    • You must set the value of the <form> tag's enctype attribute to multipart/form-data.

    • The form must contain an <input> tag that identifies the video file, and the value of the name attribute for that tag must be file.

    • The form must contain a hidden <input> tag that specifies the token value parsed from the API response in step 3. The value of the name attribute for that tag must be token.

    The following code shows a sample form.

    // place to redirect user after upload
    $nextUrl = 'http://www.example.com/youtube_uploads';
    
    // build the form
    $form = '<form action="'. $postUrl .'?nexturl='. $nextUrl .
            '" method="post" enctype="multipart/form-data">'. 
      	'<input name="file" type="file"/>'. 
      	'<input name="token" type="hidden" value="'. $tokenValue .'"/>'.
      	'<input value="Upload Video File" type="submit" />'. 
      	'</form>';
    
  5. After uploading the video file, the user is redirected to the nexturl specified in your form. If the upload was successful, YouTube appends id and status parameters to the URL as shown in the following example:

    http://www.example.com/youtube_uploads?status=200&id=JPF-DXF7hzc

    If the upload was not successful, YouTube appends status and code parameters to the URL to help you diagnose the cause of the failure. The reference guide provides more information about these parameters.

Checking upload status

After a user uploads a video, it will immediately be visible in the authenticated user's uploads feed:

http://gdata.youtube.com/feeds/api/users/default/uploads

However, the video will not be publicly visible on YouTube until YouTube has finished processing the video. In addition, videos that YouTube rejected or that failed to upload successfully will only be listed in the authenticated user's uploads feed. The following code checks the status of a VideoEntry object to determine whether YouTube is still processing the video, failed to process the video, or rejected the video.

// Assuming that $videoEntry is the object that was returned during the upload
$state = $videoEntry->getVideoState();

if ($state) {
  echo 'Upload status for video ID ' . $videoEntry->getVideoId() . ' is ' .
    $state->getName() . ' - ' . $state->getText() . "\n";
  } else {
    echo "Not able to retrieve the video status information yet. " . 
      "Please try again later.\n";
}

Note: You can also use the $videoEntry->isVideoPrivate() helper method to check whether a video is private.

Updating and deleting videos

Updating video information

To modify the metadata for a video, update the VideoEntry object and then use the Zend_Gdata_YouTube service's updateEntry method. Note that since the updateEntry method issues an HTTP PUT request to update an existing object, the request URL must be the edit link for the video. The following code demonstrates how to retrieve a video's edit link and then update the video's description.

$putUrl = $videoEntry->getEditLink()->getHref();
$videoEntry->setVideoDescription('This description is better. Hurrah!');
$yt->updateEntry($videoEntry, $putUrl);

Please refer to the Determining whether a user can edit a video entry section for more information about editing videos.

Deleting a video

To delete a video, invoke the delete method on the Zend_Gdata_YouTube service object, passing in the VideoEntry object that is being deleted. For example, you could retrieve the uploaded videos feed for the authenticated user and then delete a video selected by the user.

$yt->delete($videoEntryToDelete);

Note: The authenticated user must be the owner of the video that is being deleted.

Using community features

Adding a rating

A user can add a rating to a video. YouTube uses a 1-5 rating system in which 1 is the lowest rating that can be given. Users cannot update or delete ratings. Typically, a user would rate a video after watching that video.

To rate a video, insert a Rating object to the ratings feed URL for the VideoEntry that is being rated. The following code shows how to add a rating to a video:

// $yt must be a fully authenticated Zend_Gdata_YouTube service object

$videoEntryToRate->setVideoRating(2);
$ratingUrl = $videoEntryToRate->getVideoRatingsLink()->getHref();

try {
  $ratedVideoEntry = $yt->insertEntry( $videoEntryToRate, $ratingUrl, 
    'Zend_Gdata_YouTube_VideoEntry');
} catch (Zend_Gdata_App_HttpException $httpException) {
  echo $httpException->getRawResponseBody();
}

Comments

A comment is a text response to a video. Logged-in users can add comments to a video but cannot modify or delete those comments. In addition, please note that YouTube will convert any HTML markup that appears in a comment into plain text. Typically, a user would add a comment to a video after watching that video.

Retrieving video comments

The following code demonstrates how to retrieve the comments feed URL from a VideoEntry object and then print the comments for the video.

getAndPrintCommentFeed($videoEntry->videoId);

function getAndPrintCommentFeed($videoId)
{
  $yt = new Zend_Gdata_YouTube();
  // set the version to 2 to retrieve a version 2 feed
  $yt->setMajorProtocolVersion(2);
  $commentFeed = $yt->getVideoCommentFeed($videoId);
  printCommentFeed($commentFeed);
}

function printCommentFeed($commentFeed) 
{
  $count = 1;
  foreach ($commentFeed as $commentEntry) {
    echo 'Entry # ' . $count . "\n";
    printCommentEntry($commentEntry);
    echo "\n";
    $count++;
  }
}

function printCommentEntry($commentEntry) 
{
  echo 'Comment: ' . $commentEntry->title->text . "\n";
  echo "Full text: " . $commentEntry->content->text . "\n";
  echo "Author: " . $commentEntry->author[0]->name->text . "\n";
}

Adding a comment

To add a comment to a video, insert a Zend_Gdata_YouTube_CommentEntry (CommentEntry) object into the comments feed URL for the video. The following code demonstrates how to add a new comment for a video:

$newComment = $yt->newCommentEntry();
$newComment->content = $yt->newContent()->setText('new comment');

// post the comment to the comments feed URL for the video
$commentFeedPostUrl = $videoEntry->getVideoCommentFeedUrl();
$updatedVideoEntry = $yt->insertEntry($newComment, $commentFeedPostUrl,
  'Zend_Gdata_YouTube_CommentEntry');

Video Responses

Retrieving video responses for a video

A video response is a video that is associated, as a reply, with a second video. A video can be designated as a video response to exactly one other video. An authenticated user can add or delete video responses, but the user must have uploaded a video to modify that video's video response status.

Each video entry in a video feed can have an associated video response feed. That feed, which lists all of the video responses to the video described in the video entry, is itself a video feed.

The following code demonstrates how to retrieve and print information about the video responses for a given VideoEntry.

function getAndPrintVideoResponses($videoEntry)
{
  $responsesFeedUrl = $videoEntry->getVideoResponsesLink()->getHref();
  getAndPrintVideoFeed($responsesFeedUrl); 
}

This example reuses the getAndPrintVideoFeed() function described in the Displaying a feed of videos section. In this example, the video responses feed URL is retrieved dynamically by invoking VideoEntry->getVideoResponsesLink()->getHref().

Adding a video response

To add a video response, which is identified by a VideoEntry object, insert it into the video responses feed URL for the original video. The following code demonstrates how to retrieve the video responses feed URL for a video and then add a new video response to the feed.

$responsesFeedUrl = $videoEntry->getVideoResponsesLink()->getHref();
$yt->insertEntry($videoResponseEntry, $responsesFeedUrl);

Note: A video owner has the opportunity to review and approve all video responses to the owner's videos. A video response will only be included in a video responses feed if the video owner has approved the response.

Deleting a video response

The currently authenticated user can delete a video from a video responses feed if she is the owner of the video that was responded to. The following code demonstrates how to delete a video response:

// obtain the URL for the video responses feed
// $yt must be a fully authenticated service object
$videoThatHasResponses = $yt->getVideoEntry('abc123');
$responseFeedUrl = $videoThatHasResponses->getVideoResponsesLink()->getHref();

$idOfVideoResponseToBeDeleted = 'xyz123';
$yt->delete($responseFeedUrl . '/' . $idOfVideoResponseToBeDeleted);

Flagging a video

To post a complaint about a video, insert an Atom entry containing the complaint to the complaints link for the VideoEntry object that describes that video. The entry specifies a complaint category as well as the full text of the complaint. The following code demonstrates how to flag a video:

$complaintUrl = $badVideoEntry->getVideoComplaintsLink()->getHref();
$complaintEntry = $yt->newEntry();
$newComplaint->content = $yt->newContent()->setText('This video is inappropriate.');

// then use the $yt service to insert the entry
try {
  $yt->insertEntry($complaintEntry, $complaintUrl);
} catch (Zend_App_Exception $e) {
  echo $e->getMessage();
}

Saving and collecting videos

Favorite videos

Retrieving a user's favorite videos

YouTube users can choose to mark videos that they watch as favorite videos. A user's favorite videos feed can be retrieved from the following URL:

http://gdata.youtube.com/feeds/api/users/username/favorites

Note: Using the string default instead of a username retrieves the favorite videos of the currently authenticated user.

To retrieve a user's favorite videos, request a feed from the Zend_Gdata_YouTube service object as shown in the example below, which retrieves and prints a specified user's favorite videos. The returned feed is a regular video feed, which contains VideoEntry objects.

// optionally specify version 2 to retrieve a v2 feed
$yt->setMajorProtocolVersion(2);
$favoritesFeed = $yt->getUserFavorites($userName);

Adding a favorite video

To add a favorite video, use the Zend_Gdata_YouTube service object's insertEntry method to post the video, which is identified by a regular VideoEntry object, to the authenticated user's favorite videos feed.

// Either specify the URL of the favorite feed itself, or get it from the object
$yt->insertEntry($newFavoriteVideoEntry, $favoritesFeed->getSelfLink()->href);

Deleting a favorite video

To delete a favorite video from the currently authenticated user's favorite videos feed, call the delete method on the VideoEntry object that corresponds to the favorite video you want to delete.

$favoriteVideoEntry->delete();

Note: You must retrieve the VideoEntry object that identifies the favorite video from the authenticated user's favorite videos feed. Otherwise, your request will attempt to delete the actual video itself.

Playlists

A YouTube user's playlists feed contains a list of that user's playlists, with each feed entry corresponding to a single playlist. The client library enables you to retrieve, add, update and delete playlists. It also lets you retrieve a list of the videos in a single playlist as well as add, update or delete playlist videos. The client library uses the following objects to work with playlists:

Retrieving a user's playlists

To retrieve a feed of a particular user's playlists, you use the following URL:

http://gdata.youtube.com/feeds/api/users/username/playlists

Note: Using the string default instead of a username retrieves the profile of the currently authenticated user.

The following code demonstrates how to retrieve and print information about a particular user's playlists:

function getAndPrintPlaylistListFeed($userName, $showPlaylistContents)
{
  $yt = new Zend_Gdata_YouTube();
  // optionally set version to 2 to retrieve a version 2 feed
  $yt->setMajorProtocolVersion(2);
  $playlistListFeed = $yt->getPlaylistListFeed($userName);
  printPlaylistListFeed($playlistListFeed, $showPlaylistContents);
}

function printPlaylistListFeed($playlistListFeed, $showPlaylistContents)
{
  $count = 1;
  foreach ($playlistListFeed as $playlistListEntry) {
    echo 'Entry # ' . $count . "\n";

    // This function is defined in the next section
    printPlaylistListEntry($playlistListEntry, $showPlaylistContents);

    echo "\n";
    $count++;
  }
}

Retrieving playlist information

The following code demonstrates how to use a PlaylistListEntry, as retrieved in the previous example, to retrieve and print information about the videos in that playlist.

// print the metadata of the playlist entry itself
echo 'Title: ' . $playlistListEntry->title->text . "\n";
echo 'Description: ' . $playlistListEntry->description->text . "\n";

// assuming $yt is a fully authenticated service object, set the version to 2
// to retrieve additional metadata such as yt:uploaded and media:credit
$yt->setMajorProtocolVersion(2);

$playlistVideoFeed =
  $yt->getPlaylistVideoFeed($playlistListEntry->getPlaylistVideoFeedUrl());

foreach ($playlistVideoFeed as $playlistVideoEntry) {
  // we can reuse our printVideoEntry function defined earlier to get all the regular video meta-data
  printVideoEntry($playlistVideoEntry);
  
  // in version 2, the following details are also available for playlist entries
  echo 'Video originally uploaded on: ' .
    $playlistVideoEntry->getMediaGroup()->getUploaded()->text . "\n";
  
  // we can also obtain the media:credit element, which tells us whether the 
  // video was uploaded by a partner
  $mediaCredit = $playlistVideoEntry->getMediaGroup()->getMediaCredit();
  if ($mediaCredit) {

    echo 'Video originally uploaded by ' . $mediaCredit->text . "\n";
    echo 'Media credit role: ' . $mediaCredit->getRole() . "\n";
    
    // if the yt:type attribute is present, then the video was uploaded
    // by a YouTube partner
    echo 'Media credit type: ' . $mediaCredit->getYTtype() . "\n";
  }
}

In the PHP client library code, the printPlaylistListEntry() function accepts an optional boolean parameter named showPlaylistContents. If that parameter is set to true, the function will print the list of videos in the playlist.

Adding a playlist

To add a new playlist, use the Zend_Gdata_YouTube service object to create the playlist and then insert it into the authenticated user's playlists feed.

$newPlaylist = $yt->newPlaylistListEntry();
$newPlaylist->description = $yt->newDescription()->setText('description of my new playlist');
$newPlaylist->title = $yt->newTitle()->setText('title of my new playlist');
// post the new playlist
$postLocation = 'http://gdata.youtube.com/feeds/api/users/default/playlists';
try {
  $yt->insertEntry($newPlaylist, $postLocation);
} catch (Zend_Gdata_App_Exception $e) {
  echo $e->getMessage();
}

Updating a playlist

You can use the API to update a playlist's title, description and or public/private status. To update a playlist, modify the PlaylistListEntry object for that playlist and then call the object's save method.

The following code updates a playlist's description.

$playlistToBeUpdated->description->setText('updated playlist description');
$playlistToBeUpdated->save();

Adding a video to a playlist

You can add a video to a playlist by using a VideoEntry object. The following code retrieves a VideoEntry object with a known entry ID and then adds it to the playlist corresponding to the PlaylistListEntry object. Since the request does not specify a position where the video will appear in the playlist, the new video is added to the end of the playlist.

$postUrl = $playlistToAddTo->getPlaylistVideoFeedUrl();
// video entry to be added
$videoEntryToAdd = $yt->getVideoEntry('4XpnKHJAok8');

// create a new Zend_Gdata_PlaylistListEntry, passing in the underling DOMElement of the VideoEntry
$newPlaylistListEntry = $yt->newPlaylistListEntry($videoEntryToAdd->getDOM());

// post
try {
  $yt->insertEntry($newPlaylistListEntry, $postUrl);
} catch (Zend_App_Exception $e) {
  echo $e->getMessage();
}

Editing information for a playlist video

You can modify the position of each video in a playlist by updating the PlaylistVideoEntry object for the video and calling its update method.

// get a Zend_Gdata_PlaylistVideoEntry from the feed generated by $yt->getPlaylistVideoFeedUrl
// move to top of playlist by setting position to 0
$playlistVideoEntryToBeModified->setPosition($yt->newPosition(0));

// update by putting the new entry to the entry's edit link
try {
  $yt->updateEntry($playlistVideoEntryToBeModified, $playlistVideoEntryToBeModified->getEditLink()->getHref());
}

Removing a video from a playlist

To remove a video from a playlist, use the delete method of the PlaylistVideoEntry.

$playlistVideoEntry->delete();

Deleting a playlist

To delete a playlist, call the delete method of the corresponding PlaylistListEntry object.

$playlistListEntry->delete();

Subscriptions

Retrieving a user's subscriptions

To fetch a list of the channels, favorite video lists and search queries that a given user has subscribed to, send a request to the following URL:

http://gdata.youtube.com/feeds/api/users/username/subscriptions

Note: Using the string default instead of a username retrieves the currently authenticated user's subscriptions.

The following code demonstrates how to retrieve and print the list of subscriptions for a given user:

// assuming that $yt is a fully authenticated YouTube service object
// optionally set the version to 2 to retrieve a v2 feed
$yt->setMajorProtocolVersion(2);
// enter the username of the user whose subscriptions you want to retrieve 
$subscriptionFeed = $yt->getSubscriptionFeed($userName);

// loop through feed entries and print information about each subscription
foreach($subscriptionFeed as $subscriptionEntry) {
  $subscriptionType = null;
  // get the array of categories to find out what type of subscription it is
  $categories = $subscriptionEntry->getCategory();
  // examine the correct category element since there are multiple
  foreach($categories as $category) {
    if ($category->getScheme() == 'http://gdata.youtube.com/schemas/2007/subscriptiontypes.cat') {
      $subscriptionType = $category->getTerm();
    }
  }

  switch ($subscriptionType) {
    case 'channel':
      echo 'Subscription to channel: ' . $subscriptionEntry->getUsername()->text . "\n";
      break;
    case 'query':
      echo 'Subscription to search term: ' . $subscriptionEntry->getQueryString() . "\n";
      break;
    case 'favorites':
      echo 'Subscription to favorites of user ' . $subscriptionEntry->getUsername()->text . "\n";
      break;
    case 'playlist':
      echo 'Subscription to playlist ' . $subscriptionEntry->getPlaylistTitle() . 
        ' of user ' . $subscriptionEntry->getUsername()->text . "\n";
      break;
  }
}

Adding a subscription

You can create a new subscription by inserting a new Zend_Gdata_YouTube_SubscriptionEntry (SubscriptionEntry) into the authenticated user's subscriptions feed. Users can subscribe to another user's channel, another user's list of favorite videos, a playlist or a search query.

Subscribing to a channel

The following code subscribes the authenticated user to the "GoogleDevelopers" channel.

// this example assumes that $yt is a fully authenticated service object
$subscriptionsFeedUrl = "http://gdata.youtube.com/feeds/api/users/default/subscriptions";
$newSubscription = $yt->newSubscriptionEntry();

$channel = 'GoogleDevelopers';
$newSubscription->setUsername(new Zend_Gdata_YouTube_Extension_Username($channel));

// post
$yt->insertEntry($newSubscription, $subscriptionsFeedUrl);
Subscribing to a list of favorite videos

The following code subscribes the authenticated user to the "GoogleDevelopers" user's list of favorite videos:

// this example assumes that $yt is a fully authenticated service object
$subscriptionsFeedUrl = "http://gdata.youtube.com/feeds/api/users/default/subscriptions";
$newSubscription = $yt->newSubscriptionEntry();

$channel = 'GoogleDevelopers';
$newSubscription->setUsername(new Zend_Gdata_YouTube_Extension_Username($channel));
$newSubscription->category = array(
  $yt->newCategory('favorites',
                      'http://gdata.youtube.com/schemas/2007/subscriptiontypes.cat'));

// post
$yt->insertEntry($newSubscription, $subscriptionsFeedUrl);
Subscribing to a playlist

The following code subscribes the authenticated user to the Android playlist, which has the playlist ID 586D322B5E2764CF, in the 'GoogleDevelopers' channel.

// this example assumes that $yt is a fully authenticated service object
$subscriptionsFeedUrl = "http://gdata.youtube.com/feeds/api/users/default/subscriptions";

// since this feature is only available in version 2 of the API,
// you need to set the protocol version to 2
$newSubscription->setMajorProtocolVersion(2);

$newSubscription = $yt->newSubscriptionEntry();

$channel = 'GoogleDevelopers';
$newSubscription->setUsername(new Zend_Gdata_YouTube_Extension_Username($channel));
$newSubscription->category = array(
  $yt->newCategory('playlist',
                      'http://gdata.youtube.com/schemas/2007/subscriptiontypes.cat'));
// set the id of the playlist
$newSubscription->setPlaylistId(new Zend_Gdata_YouTube_Extension_PlaylistId('586D322B5E2764CF'));

// post
$yt->insertEntry($newSubscription, $subscriptionsFeedUrl);
Subscribing to a search query

The following code subscribes the authenticated user to videos that match the search term "puppies":

// this example assumes that $yt is a fully authenticated service object
$subscriptionsFeedUrl = "http://gdata.youtube.com/feeds/api/users/default/subscriptions";
$newSubscription = $yt->newSubscriptionEntry();
$newSubscription->setQueryString(new Zend_Gdata_YouTube_Extension_QueryString('puppies'));

// post
$yt->insertEntry($newSubscription, $subscriptionsFeedUrl);

Deleting a subscription

To delete a subscription, call the delete method on the corresponding SubscriptionEntry object.

$subscriptionEntry->delete();

Enabling user interaction

Profiles

Retrieving a user's profile

To retrieve a user's profile, send a request to the following URL:

http://gdata.youtube.com/feeds/api/users/username

Note: Using the string default instead of a username retrieves the profile of the currently authenticated user.

The following code prints out a number of attributes from a specified user's profile:

function getAndPrintUserProfile($userName) 
{
  $yt = new Zend_Gdata_YouTube();

  // set protocol version to 2 to retrieve a v2 profile entry,
  // which contains additional information from the user's profile
  $yt->setMajorProtocolVersion(2);

  // enter a username or set the $userName variable to 'default'
  // to retrieve the currently authenticated user's profile
  $userProfileEntry = $yt->getUserProfile($userName);

  echo $userProfileEntry->title->text . "\n";
  echo "Profile Information\n";
  echo 'Username: ' . $userProfileEntry->getUsername() . "\n";
  echo 'Profile picture url ' . $userProfileEntry->getThumbnail()->getUrl() . "\n";
  echo 'About me: ' . $userProfileEntry->getAboutMe() . "\n";
  echo 'Website (URL): ' . $userProfileEntry->getLink('related')->getHref() . "\n";
  echo "Personal Details\n";
  echo 'Age : ' . $userProfileEntry->getAge() . "\n";
  echo 'Gender: ' . $userProfileEntry->getGender() . "\n";
  echo 'Relationship: ' . $userProfileEntry->getRelationship() . "\n";
  echo 'Hometown: ' . $userProfileEntry->getHometown() . "\n";
  echo 'Location ' . $userProfileEntry->getLocation() . "\n";
  echo "Interests\n";
  echo 'Hobbies: ' . $userProfileEntry->getHobbies() . "\n";
  echo 'Books: ' . $userProfileEntry->getBooks() . "\n";
  echo 'Movies: ' . $userProfileEntry->getMovies() . "\n";
  echo 'Music: ' . $userProfileEntry->getMusic() . "\n";
  echo "Jobs \ Career \ Education\n";
  echo 'Occupation: ' . $userProfileEntry->getOccupation() . "\n";
  echo 'Companies: ' . $userProfileEntry->getCompany() . "\n";
  echo 'School: ' . $userProfileEntry->getSchool() . "\n";
  echo 'Member since ' . $userProfileEntry->getPublished()->text . "\n";
  echo 'Last profile update on ' . $userProfileEntry->getUpdated()->text . "\n";

  // retrieve counts of favorites, contacts, subscriptions and uploads
  // by examining the feedLink elements in the profile
  echo "Additional video count information\n";
  echo $userProfileEntry->getFeedLink(
    'http://gdata.youtube.com/schemas/2007#user.favorites')->countHint . " favorite videos.\n";
  echo $userProfileEntry->getFeedLink(
    'http://gdata.youtube.com/schemas/2007#user.contacts')->countHint . " user contacts.\n";
  echo $userProfileEntry->getFeedLink(
    'http://gdata.youtube.com/schemas/2007#user.subscriptions')->countHint . " subscriptions.\n";
  echo $userProfileEntry->getFeedLink(
    'http://gdata.youtube.com/schemas/2007#user.uploads')->countHint . " video uploads.\n";

  // examine the yt:statistics element for further information
  $statistics = $userProfileEntry->getStatistics();
  echo 'User channel viewed ' . $statistics->getViewCount() . " times.\n";

  // look in the extension attributes for more information
  $extensionAttributes = $statistics->getExtensionAttributes();
  echo $extensionAttributes['videoWatchCount']['value'] . " videos watched\n";
  echo $extensionAttributes['subscriberCount']['value'] . " subscribers \n";
  echo 'Last login on ' . $extensionAttributes['lastWebAccess']['value'] . "\n";
}

Note: The client library uses overloaded magic methods, which are only available in PHP 5.2. If you are using PHP 5.1, you will need to modify the calls in the sample code to print profile details. For example, you would need to change $userProfileEntry->getAge() to $userProfileEntry->getAge()->getTitle(). Future versions of the client library will provide helper methods to simplify the retrieval of additional profile elements that are currently in the extensionAttributes array.

Contacts

Retrieving a user's contacts

To retrieve a list of a user's contacts, send a request to the following URL:

http://gdata.youtube.com/feeds/api/users/username/contacts

The following code demonstrates how to retrieve and print the contacts of a specified user:

function getAndPrintContactsFeed($userName) 
{
  $yt = new Zend_Gdata_YouTube();
  $contactsFeed = $yt->getContactsFeed($userName);
  printContactsFeed($contactsFeed);
}

function printContactsFeed($contactsFeed)
{
  $count = 1;
  echo $contactsFeed->title->text . "\n";
  foreach ($contactsFeed as $contactsEntry) {
    echo 'Entry # ' . $count . "\n";
    printContactsEntry($contactsEntry);
    echo "\n";
    $count++;
  }
}

function printContactsEntry($contactsEntry)
{
  echo 'Contact: ' . $contactsEntry->title->text . "\n";
  foreach ($contactsEntry->category as $category) {
    if ($category->scheme == 'http://schemas.google.com/g/2005#kind') {
      $type = $category->term;
    }
  }
  echo "\tType: " . $type . "\n";
}

Adding a contact

To add a contact, use the insertEntry method of the Zend_Gdata_YouTube service object to insert the contact to the authenticated user's contacts feed. The request can specify any number of user-defined categories to associate the contact with groups, such as "Family", "Bowling Enthusiasts," "Wizards" and so forth. The example below adds a contact with the username "GoogleDevelopers" to the "Cool Dudes" category.

$newContact = $yt->newContactEntry();
$newContact->username = $yt->newUsername('GoogleDevelopers');
$newContact->category = 
  array($yt->newCategory('Cool Dudes',
                            'http://gdata.youtube.com/schemas/2007/contact.cat'));
$yt->insertEntry($newContact, $contactFeedUrl);

Accepting or rejecting a contact

You can accept or reject a contact by updating the status of the corresponding Zend_Gdata_YouTube_ContactEntry (ContactEntry) object.

The following example shows how to accept a contact:

$contactEntry->setStatus($yt->newStatus('accepted'));
$contactEntry->save();

The following example shows how to reject a contact:

$contactEntry->setStatus($yt->newStatus('rejected'));
$contactEntry->save();

Deleting a contact

To delete a contact, call the delete method on the ContactEntry that you are deleting.

$contactEntry->delete();

Messages

The API enables you to send messages between YouTube users who have mutually accepted each other as contacts. All messages sent through the API must include a VideoEntry.

Retrieving messages

To retrieve the contents of a user's inbox, make an authenticated request to the following URL:

http://gdata.youtube.com/feeds/api/users/username/inbox

The following example prints the contents of the authenticated user's inbox. It fetches a Zend_Gdata_YouTube_InboxFeed (InboxFeed), which contains a Zend_Gdata_YouTube_InboxEntry (InboxEntry) for each message in the user's inbox.

// Assuming that $yt is a valid and authenticated Zend_Gdata_YouTube object

$inboxFeed = $yt->getInboxFeedForCurrentUser();

foreach($inboxFeed as $inboxEntry) {
  echo "Message title: " . $inboxEntry->getTitle()->text . "\n";

  $authors = $inboxEntry->getAuthor();
  $author = $authors[0];
  echo "Sent from: " . $author->name->text . "\n";

  // See if there was a custom message body sent:
  $body = $inboxEntry->getSummary();
  if ($body != null) {
    echo "Message body: " . $body->text . "\n";
  }

  // Since each message contains a video, we can request similar
  // metadata, such as ratings, etc.
  echo "Average rating: " . $inboxEntry->getRating()->average . "\n";
}

Sending a message

All messages must contain a YouTube video. To use the sendVideoMessage method, you need to pass either a valid VideoEntry object or the Id string of a valid video.

The following code sends a message containing a video to a user identified by the variable $recipientUserName:

// Assuming that $yt is a valid and authenticated Zend_Gdata_YouTube object
$body = 'Here is a video that you may find interesting';

$recipientUserName = 'gdpython'; # Note this must be a valid username.
$videoId = 'ylLzyHk54Z0'; # This must be the Id of a valid video.

// insert the message
try {
  // In this example, the third parameter specifies the videoId.
  // Instead of specifying a videoId, you could also provide a valid
  // Zend_Gdata_YouTube_VideoEntry object as the value of the second parameter.
  $sentMessage =
    $yt->sendVideoMessage($body, null, $videoId, $recipientUserName);
} catch (Zend_Gdata_App_HttpException $e) {
  echo 'Something went wrong ' . $e->getMessage() . "\n";
  echo 'Raw HTTP response ' . $e->getRawResponseBody() . "\n";
}

Note: The recipient of the message must be an accepted contact of the sender of the message.

Deleting a message

To delete a message, call the delete method on a MediaEntry object:

$mediaEntry->delete();

Activity feeds

Activity feeds list actions that a particular user or set of users has taken on the YouTube site. The API enables you to retrieve two types of activity feeds:

  • A user activity feed identifies actions taken by one or more users who are specified in the API request.
  • A friend activity feed identifies actions that an authenticated user's friends have recently taken on the YouTube site.

Activity feeds list the following user actions:

  • Rating a video
  • Sharing a video
  • Marking a video as a favorite
  • Commenting on a video
  • Uploading a video
  • Adding a friend
  • Creating a subscription to a channel

Note: Activity feed support for the PHP is only available in Zend_Gdata release 1.7.5 and later.

The following sections explain how to retrieve and process activity feeds:

User activity feeds
 
Friend activity feeds
 

User activity feeds

To retrieve a user activity feed, make an authenticated request to the following URL. In the request, set the author parameter value to a comma-delimited list of up to 20 YouTube usernames. The API response will contain activities performed by any of those users.

http://gdata.youtube.com/feeds/api/events?author=usernames

The following example sets a list of usernames, retrieves an activity feed for those users, and then prints out some information about each event in the activity feed:

// this example assumes that $yt is a fully authenticated YouTube service object
$yt->setMajorProtocolVersion(2);

$activityFeed = $yt->getActivityForUser("username1,username2,username3");
printActivityFeed($activityFeed);

/**
 * Print out an activity feed
 *
 * @param $activityFeed A Zend_Gdata_YouTube_ActivityFeed
 * @return void
 */
function printActivityFeed($activityFeed) {
  foreach($activityFeed as $activityEntry) {
    $author = $activityEntry->getAuthorName();
    $activityType = $activityEntry->getActivityType();
    switch ($activityType) {
      case 'video_rated':
        echo "$author rated video " . $activityEntry->getVideoId()->text . ' ' .
          $activityEntry->getRatingValue() . " stars\n";
        break;
      case 'video_shared':
        echo "$author shared video " . $activityEntry->getVideoId()->text . "\n";
        break;
      case 'video_favorited':
        echo "$author favorited video " . $activityEntry->getVideoId()->text . "\n";
        break;
      case 'video_commented':
        echo "$author commented on video " . $activityEntry->getVideoId()->text . "\n";
        break;
      case 'video_uploaded':
        echo "$author uploaded video " . $activityEntry->getVideoId()->text . "\n";
        break;
      case 'friend_added':
        echo "$author friended " . $activityEntry->getUsername()->text . "\n";
        break;
      case 'user_subscription_added':
        echo "$author subscribed to channel of " . 
          $activityEntry->getUsername()->text . "\n";
        break;
    }
  }
}

Friend activity feeds

To retrieve a friend activity feed, make an authenticated request to the following URL. Note that a user can only retrieve the friend activity feed for her own friends.

http://gdata.youtube.com/feeds/api/users/default/friendsactivity

The following example retrieves the logged-in user's friend activity feed and then prints information about each event in the feed:

// this example assumes that $yt is a fully authenticated YouTube service object
$yt->setMajorProtocolVersion(2);

$friendActivityFeed = $yt->getFriendActivityForCurrentUser();
printActivityFeed($friendActivityFeed);

Conclusion

Questions? Feedback? Notice a typo in this doc? Let us know in the discussion forum. Happy coding!