# Using the YouTube Data API

The YouTube Data API offers read and write access to YouTube's content. Users can perform unauthenticated requests to Google Data feeds to retrieve feeds of popular videos, comments, public information about YouTube user profiles, user playlists, favorites, subscriptions and so on.

For more information on the YouTube Data API, please refer to the official PHP Developer's Guide on code.google.com.

## Authentication

The YouTube Data API allows read-only access to public data, which does not require authentication. For any write requests, a user needs to authenticate either using ClientLogin or AuthSub authentication. Please refer to the Authentication section in the PHP Developer's Guide for more detail.

## Developer Keys and Client ID

A developer key identifies the YouTube developer that is submitting an API request. A client ID identifies your application for logging and debugging purposes. Please visit http://code.google.com/apis/youtube/dashboard/ to obtain a developer key and client ID. The example below demonstrates how to pass the developer key and client ID to the Zend_Gdata_YouTube service object.

Passing a Developer Key and ClientID to Zend_Gdata_YouTube

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

## Retrieving public video feeds

The YouTube Data API provides numerous feeds that return a list of videos, such as standard feeds, related videos, video responses, user's uploads, and user's favorites. For example, the user's uploads feed returns all videos uploaded by a specific user. See the YouTube API reference guide for a detailed list of available feeds.

### Searching for videos by metadata

You can retrieve a list of videos that match specified search criteria, using the YouTubeQuery class. The following query looks for videos which contain the word "cat" in their metadata, starting with the 10th video and displaying 20 videos per page, ordered by the view count.

Searching for videos

    $yt = new Zend_Gdata_YouTube();
    $query = $yt->newVideoQuery();
    $query->videoQuery = 'cat';
    $query->startIndex = 10;
    $query->maxResults = 20;
    $query->orderBy = 'viewCount';

    echo $query->queryUrl . "\n";
    $videoFeed = $yt->getVideoFeed($query);

    foreach ($videoFeed as $videoEntry) {
        echo "---------VIDEO----------\n";
        echo "Title: " . $videoEntry->getVideoTitle() . "\n";
        echo "\nDescription:\n";
        echo $videoEntry->getVideoDescription();
        echo "\n\n\n";
    }

For more details on the different query parameters, please refer to the Reference Guide. The available helper functions in Zend_Gdata_YouTube_VideoQuery for each of these parameters are described in more detail in the PHP Developer's Guide.

### Searching for videos by categories and tags/keywords

Searching for videos in specific categories is done by generating a specially formatted URL. For example, to search for comedy videos which contain the keyword dog:

Searching for videos in specific categories

    $yt = new Zend_Gdata_YouTube();
    $query = $yt->newVideoQuery();
    $query->category = 'Comedy/dog';

    echo $query->queryUrl . "\n";
    $videoFeed = $yt->getVideoFeed($query);

### Retrieving standard feeds

The YouTube Data API has a number of standard feeds. These standard feeds can be retrieved as Zend_Gdata_YouTube_VideoFeed objects using the specified URLs, using the predefined constants within the Zend_Gdata_YouTube class (Zend_Gdata_YouTube::STANDARD_TOP_RATED_URI for example) or using the predefined helper methods (see code listing below).

To retrieve the top rated videos using the helper method:

Retrieving a standard video feed

    $yt = new Zend_Gdata_YouTube();
    $videoFeed = $yt->getTopRatedVideoFeed();

There are also query parameters to specify the time period over which the standard feed is computed.

For example, to retrieve the top rated videos for today:

Using a Zend_Gdata_YouTube_VideoQuery to Retrieve Videos

    $yt = new Zend_Gdata_YouTube();
    $query = $yt->newVideoQuery();
    $query->setTime('today');
    $videoFeed = $yt->getTopRatedVideoFeed($query);

Alternatively, you could just retrieve the feed using the URL:

Retrieving a video feed by URL

    $yt = new Zend_Gdata_YouTube();
    $url = 'http://gdata.youtube.com/feeds/standardfeeds/top_rated?time=today'
    $videoFeed = $yt->getVideoFeed($url);

### Retrieving videos uploaded by a user

You can retrieve a list of videos uploaded by a particular user using a simple helper method. This example retrieves videos uploaded by the user 'liz'.

Retrieving videos uploaded by a specific user

    $yt = new Zend_Gdata_YouTube();
    $videoFeed = $yt->getUserUploads('liz');

### Retrieving videos favorited by a user

You can retrieve a list of a user's favorite videos using a simple helper method. This example retrieves videos favorited by the user 'liz'.

Retrieving a user's favorite videos

    $yt = new Zend_Gdata_YouTube();
    $videoFeed = $yt->getUserFavorites('liz');

### Retrieving video responses for a video

You can retrieve a list of a video's video responses using a simple helper method. This example retrieves video response for a video with the ID 'abc123813abc'.

Retrieving a feed of video responses

    $yt = new Zend_Gdata_YouTube();
    $videoFeed = $yt->getVideoResponseFeed('abc123813abc');

## Retrieving video comments

The comments for each YouTube video can be retrieved in several ways. To retrieve the comments for the video with the ID 'abc123813abc', use the following code:

Retrieving a feed of video comments from a video ID

    $yt = new Zend_Gdata_YouTube();
    $commentFeed = $yt->getVideoCommentFeed('abc123813abc');

    foreach ($commentFeed as $commentEntry) {
        echo $commentEntry->title->text . "\n";
        echo $commentEntry->content->text . "\n\n\n";
    }

Comments can also be retrieved for a video if you have a copy of the Zend_Gdata_YouTube_VideoEntry object:

Retrieving a Feed of Video Comments from a Zend_Gdata_YouTube_VideoEntry

    $yt = new Zend_Gdata_YouTube();
    $videoEntry = $yt->getVideoEntry('abc123813abc');
    // we don't know the video ID in this example, but we do have the URL
    $commentFeed = $yt->getVideoCommentFeed(null,
                                            $videoEntry->comments->href);

## Retrieving playlist feeds

The YouTube Data API provides information about users, including profiles, playlists, subscriptions, and more.

### Retrieving the playlists of a user

The library provides a helper method to retrieve the playlists associated with a given user. To retrieve the playlists for the user 'liz':

Retrieving the playlists of a user

    $yt = new Zend_Gdata_YouTube();
    $playlistListFeed = $yt->getPlaylistListFeed('liz');

    foreach ($playlistListFeed as $playlistEntry) {
        echo $playlistEntry->title->text . "\n";
        echo $playlistEntry->description->text . "\n";
        echo $playlistEntry->getPlaylistVideoFeedUrl() . "\n\n\n";
    }

### Retrieving a specific playlist

The library provides a helper method to retrieve the videos associated with a given playlist. To retrieve the playlists for a specific playlist entry:

Retrieving a specific playlist

    $feedUrl = $playlistEntry->getPlaylistVideoFeedUrl();
    $playlistVideoFeed = $yt->getPlaylistVideoFeed($feedUrl);

## Retrieving a list of a user's subscriptions

A user can have several types of subscriptions: channel subscription, tag subscription, or favorites subscription. A Zend_Gdata_YouTube_SubscriptionEntry is used to represent individual subscriptions.

To retrieve all subscriptions for the user 'liz':

Retrieving all subscriptions for a user

    $yt = new Zend_Gdata_YouTube();
    $subscriptionFeed = $yt->getSubscriptionFeed('liz');

    foreach ($subscriptionFeed as $subscriptionEntry) {
        echo $subscriptionEntry->title->text . "\n";
    }

## Retrieving a user's profile

You can retrieve the public profile information for any YouTube user. To retrieve the profile for the user 'liz':

Retrieving a user's profile

    $yt = new Zend_Gdata_YouTube();
    $userProfile = $yt->getUserProfile('liz');
    echo "username: " . $userProfile->username->text . "\n";
    echo "age: " . $userProfile->age->text . "\n";
    echo "hometown: " . $userProfile->hometown->text . "\n";

## Uploading Videos to YouTube

Please make sure to review the diagrams in the protocol guide on code.google.com for a high-level overview of the upload process. Uploading videos can be done in one of two ways: either by uploading the video directly or by sending just the video meta-data and having a user upload the video through an HTML form.

In order to upload a video directly, you must first construct a new Zend_Gdata_YouTube_VideoEntry object and specify some required meta-data. The following example shows uploading the Quicktime video "mytestmovie.mov" to YouTube with the following properties:

Metadata used in the code-sample below

Property | Value
--- | ---
Title | My Test Movie
Category | Autos
Keywords | cars, funny
Description | My description
Filename | mytestmovie.mov
File MIME type | video/quicktime
Video private? | `FALSE`
Video location | 37, -122 (lat, long)
Developer Tags | mydevelopertag, anotherdevelopertag

The code below creates a blank Zend_Gdata_YouTube_VideoEntry to be uploaded. A Zend_Gdata_App_MediaFileSource object is then used to hold the actual video file. Under the hood, the Zend_Gdata_YouTube_Extension_MediaGroup object is used to hold all of the video's meta-data. Our helper methods detailed below allow you to just set the video meta-data without having to worry about the media group object. The $uploadUrl is the location where the new entry gets posted to. This can be specified either with the $userName of the currently authenticated user, or, alternatively, you can simply use the string 'default' to refer to the currently authenticated user.

Uploading a video

    $yt = new Zend_Gdata_YouTube($httpClient);
    $myVideoEntry = new Zend_Gdata_YouTube_VideoEntry();

    $filesource = $yt->newMediaFileSource('mytestmovie.mov');
    $filesource->setContentType('video/quicktime');
    $filesource->setSlug('mytestmovie.mov');

    $myVideoEntry->setMediaSource($filesource);

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

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

    // Optionally set some developer tags
    $myVideoEntry->setVideoDeveloperTags(array('mydevelopertag',
                                               'anotherdevelopertag'));

    // Optionally set the video's location
    $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/users/default/uploads';

    // Try to upload the video, catching a Zend_Gdata_App_HttpException
    // if availableor just a regular Zend_Gdata_App_Exception

    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 a video as private, simply use: $myVideoEntry->setVideoPrivate(); prior to performing the upload. $videoEntry->isVideoPrivate() can be used to check whether a video entry is private or not.

## Browser-based upload

Browser-based uploading is performed almost identically to direct uploading, except that you do not attach a Zend_Gdata_App_MediaFileSource object to the Zend_Gdata_YouTube_VideoEntry you are constructing. Instead you simply submit all of your video's meta-data to receive back a token element which can be used to construct an HTML upload form.

Browser-based upload

    $yt = new Zend_Gdata_YouTube($httpClient);

    $myVideoEntry= new Zend_Gdata_YouTube_VideoEntry();
    $myVideoEntry->setVideoTitle('My Test Movie');
    $myVideoEntry->setVideoDescription('My Test Movie');

    // Note that category must be a valid YouTube category
    $myVideoEntry->setVideoCategory('Comedy');
    $myVideoEntry->SetVideoTags('cars, funny');

    $tokenHandlerUrl = 'http://gdata.youtube.com/action/GetUploadToken';
    $tokenArray = $yt->getFormUploadToken($myVideoEntry, $tokenHandlerUrl);
    $tokenValue = $tokenArray['token'];
    $postUrl = $tokenArray['url'];

The above code prints out a link and a token that is used to construct an HTML form to display in the user's browser. A simple example form is shown below with $tokenValue representing the content of the returned token element, as shown being retrieved from $myVideoEntry above. In order for the user to be redirected to your website after submitting the form, make sure to append a $nextUrl parameter to the $postUrl above, which functions in the same way as the $next parameter of an AuthSub link. The only difference is that here, instead of a single-use token, a status and an id variable are returned in the URL.

Browser-based upload: Creating the HTML form

    // place to redirect user after upload
    $nextUrl = 'http://mysite.com/youtube_uploads';

    $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>';

## Checking upload status

After uploading a video, it will immediately be visible in an authenticated user's uploads feed. However, it will not be public on the site until it has been processed. Videos that have been rejected or failed to upload successfully will also only be in the authenticated user's uploads feed. The following code checks the status of a Zend_Gdata_YouTube_VideoEntry to see if it is not live yet or if it has been rejected.

Checking video upload status

    try {
        $control = $videoEntry->getControl();
    } catch (Zend_Gdata_App_Exception $e) {
        echo $e->getMessage();
    }

    if ($control instanceof Zend_Gdata_App_Extension_Control) {
        if ($control->getDraft() != null &&
            $control->getDraft()->getText() == 'yes') {
            $state = $videoEntry->getVideoState();

            if ($state instanceof Zend_Gdata_YouTube_Extension_State) {
                print 'Upload status: '
                      . $state->getName()
                      .' '. $state->getText();
            } else {
                print 'Not able to retrieve the video status information'
                      .' yet. ' . "Please try again shortly.\n";
            }
        }
    }

## Other Functions

In addition to the functionality described above, the YouTube API contains many other functions that allow you to modify video meta-data, delete video entries and use the full range of community features on the site. Some of the community features that can be modified through the API include: ratings, comments, playlists, subscriptions, user profiles, contacts and messages.

Please refer to the full documentation available in the PHP Developer's Guide on code.google.com.