Upload to Youtube with PHP


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 useAuthSub 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 behttp://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.

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:

Property Value
Title My Test Movie
Category Autos
Keywords cars, funny
Description My description
Video private? false
Developer tag mydevtag, anotherdevtag
Video location 37,-122 (lat,long)
Filename file.mov
File MIME type video/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 aZend_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 statusparameters 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 theupdateEntry 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);

3 thoughts on “Upload to Youtube with PHP

  1. After going around in circles (taking me forever), reading the YouTube documentation on google codes.. this article taught me how to do everything in 20 minutes, MAX!…
    it’s amazing…
    it’s awesome!…

    Thank you very much!… thank you!

  2. Hey there, my name’s Isiah and I sometimes blog about this subject too. I actually do have a couple of questions for you if you don’t mind.
    Could it just be me or does it seem like many of the replies seem like they are coming from brain dead individuals?😛 Also, if you’re on additional social network sites such as web 2.0 site list, I’d like
    to keep in touch. Perhaps you could post a couple links to any of them?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s