0

I'm attempting to upload a video to YouTube via the API using Zend_Gdata (Zend Framework 1.12.0). I had no problems getting direct upload to work, but browser-based upload always gives me a 400 - INVALID TOKEN error. I'm pretty sure I must be missing something vital but small enough to not notice it.

There are two files involved in this:

index.php

<?php
$youTubeAPIKey = '<API_Key>';
$username = '<user>';
$password = '<pass>';

set_include_path(get_include_path().PATH_SEPARATOR.__DIR__."/vendor");
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();

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

    $yt = new Zend_Gdata_YouTube($httpClient, "browser upload test", "Test version 0.1", $youTubeAPIKey);
    $videoEntry = new Zend_Gdata_YouTube_VideoEntry();

    $videoEntry->setVideoTitle("Test movie");
    $videoEntry->setVideoDescription("This is a test movie");
    $videoEntry->setVideoPrivate();

    // @todo This must be a valid YouTube category, how to get a list of valid categories?
    $videoEntry->setVideoCategory('Autos');
    $videoEntry->setVideoTags('cars, funny');

    // Get an upload token
    $tokenHandlerUrl = 'http://gdata.youtube.com/action/GetUploadToken';
    $tokenArray = $yt->getFormUploadToken($videoEntry, $tokenHandlerUrl);
    $token = $tokenArray['token'];
    $url = $tokenArray['url'];
    // print "Token value: {$tokenArray['token']}\n url: {$tokenArray['url']}\n";
    $nextUrl = "http://" . $_SERVER['HTTP_HOST'] . "/uploadDone.php";
}
catch (Zend_Gdata_App_HttpException $httpException)
{
    echo $httpException->getRawResponseBody();
}
catch (Zend_Gdata_App_Exception $e) {
    echo $e->getMessage();
}
catch (Exception $e)
{
    print $e->getTraceAsString();
}
?><!DOCTYPE html>
<html>
    <head>
        <title>Testing Youtube upload</title>
    </head>

    <body>
        <table>
            <tr>
                <td>
                    Url:
                </td>
                <td>
                    <?= $url ?>
                </td>
            </tr>
            <tr>
                <td>
                    Token:
                </td>
                <td>
                    <?= $token ?>
                </td>
            </tr>
        </table>
        <form action="<?= $url ?>.?nexturl=<?= urlencode($nextUrl) ?>" enctype="multipart/form-data" method="post">
            <input name="token" type="hidden" value="<?= $token ?>" />
            <input name="file" type="file" />
            <input type="submit" value="Upload file" />
        </form>
    </body>
</html>

and uploadDone.php

<?php
print nl2br(print_r($_GET, true));
print nl2br(print_r($_POST, true));

I've searched both on Stack Overflow and spent a couple of hours searching on Google but not found anything that solves it which leads me to believe I'm missing something dead simple. Any help would be appreciated.

A note: This code is only to test the API usage and is taken mostly from Google's Developer's guide (https://developers.google.com/youtube/2.0/developers_guide_php#Browser_based_Upload) and with a little help from the Yii framework documentation (http://www.yiiframework.com/wiki/375/youtube-api-v2-0-browser-based-uploading/). The production code will be rewritten in a more structured manner but that's not important at the moment.

h00ligan
  • 1,471
  • 9
  • 17
  • Are you testing with an "unlinked" Google Account that doesn't have an associated YouTube channel? There's more info at http://apiblog.youtube.com/2011/10/introducing-google-account-support-and.html – Jeff Posnick Oct 02 '12 at 19:23
  • Sorry Jeff, completely missed that you had commented. The account I'm using is an account specifically created for this purpose on the YouTube site which I hope is enough to have a linked account with its own channel. At least I can upload directly from disc to the account, just not via a web form. – h00ligan Oct 23 '12 at 16:06
  • Okay, how about the $youtubeApiKey value? Is that coming from https://code.google.com/apis/youtube/dashboard/gwt/index.html ? – Jeff Posnick Oct 23 '12 at 16:51
  • Yes, like I said, the account works just fine with direct upload but the web form upload returns this error. – h00ligan Oct 23 '12 at 21:37
  • Sorry about that—I didn't notice that there was a vertical scroll bar on the code snippet you provided and completely misinterpreted what you were trying to do. – Jeff Posnick Oct 24 '12 at 01:52
  • No problem, I've done similar myself :) – h00ligan Oct 24 '12 at 12:55

1 Answers1

1

Your action="<?= $url ?>.?nexturl=<?= urlencode($nextUrl) ?>" looks suspicious; is that an errant . character in there right after your $url variable gets evaluated, messing up the URL?

Jeff Posnick
  • 53,580
  • 14
  • 141
  • 167