Found this useful? Love this post

PHP server-side YouTube V3 OAuth API video upload guide

Dec 2014 – Please note this post is based on the 1.0.5 version of the API. If you are using the latest version you’ll need to update file paths as the file/folder structure has changed significantly.

Many bothans died to bring you this information. And when I say bothans, I refer of course to brain cells that have died as result of me smashing my head against the YouTube api.

To make this work, you’ll need to create a dummy web application that can capture the refresh token generated when you authorise your app. You can read a detailed explanation of what we’ll be doing and how the OAuth process works here.

This implementation has no requirements for any PHP frameworks (such as Zend). It is a barebones implementation based off the documentation for the YouTube V3 API utilising the Google PHP API client.

Creating your project

  1. You’ll need to head over to https://console.developers.google.com/ and create a new project.
  2. Then go and enable the YouTube Data API – (Your Project > APIS & AUTH > APIs)
  3. We’ll now need to create some credentials. Go to Your Project > APIS & AUTH > Credentials
  4. Click “Create new Client ID” and then under “Application Type” select “Web Application”.
  5. You’ll then need to enter your JavaScript origin and authorised redirect URI. I just set this to localhost, but you can set it to where ever you want.
  6. We’ve now created our client ID, we just need to fill in the Consent Screen. We can do this by navigating to Your Project > APIS & AUTH > Consent Screen. Once you’re on this page, ensure you fill out all the required fields (Email Address and Product Name).
  7. Hurray, we’ve created our project.

Getting your refresh token

I used the following PHP script as my dummy application to generate the OAuth token.

This script utilises Google APIs Client Library for PHP. You’ll need to download and install it a directory that can be read using the below script.

<?php

// Call set_include_path() as needed to point to your client library.
set_include_path($_SERVER['DOCUMENT_ROOT'] . '/directory/to/google/api/');
require_once 'Google/Client.php';
require_once 'Google/Service/YouTube.php';
session_start();

/*
 * You can acquire an OAuth 2.0 client ID and client secret from the
 * {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
 * For more information about using OAuth 2.0 to access Google APIs, please see:
 * <https://developers.google.com/youtube/v3/guides/authentication>
 * Please ensure that you have enabled the YouTube Data API for your project.
 */
$OAUTH2_CLIENT_ID = 'XXXXXXX.apps.googleusercontent.com';
$OAUTH2_CLIENT_SECRET = 'XXXXXXXXXX';
$REDIRECT = 'http://localhost/oauth2callback.php';
$APPNAME = "XXXXXXXXX";


$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
$client->setRedirectUri($REDIRECT);
$client->setApplicationName($APPNAME);
$client->setAccessType('offline');


// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);

if (isset($_GET['code'])) {
    if (strval($_SESSION['state']) !== strval($_GET['state'])) {
        die('The session state did not match.');
    }

    $client->authenticate($_GET['code']);
    $_SESSION['token'] = $client->getAccessToken();

}

if (isset($_SESSION['token'])) {
    $client->setAccessToken($_SESSION['token']);
    echo '<code>' . $_SESSION['token'] . '</code>';
}

// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
    try {
        // Call the channels.list method to retrieve information about the
        // currently authenticated user's channel.
        $channelsResponse = $youtube->channels->listChannels('contentDetails', array(
            'mine' => 'true',
        ));

        $htmlBody = '';
        foreach ($channelsResponse['items'] as $channel) {
            // Extract the unique playlist ID that identifies the list of videos
            // uploaded to the channel, and then call the playlistItems.list method
            // to retrieve that list.
            $uploadsListId = $channel['contentDetails']['relatedPlaylists']['uploads'];

            $playlistItemsResponse = $youtube->playlistItems->listPlaylistItems('snippet', array(
                'playlistId' => $uploadsListId,
                'maxResults' => 50
            ));

            $htmlBody .= "<h3>Videos in list $uploadsListId</h3><ul>";
            foreach ($playlistItemsResponse['items'] as $playlistItem) {
                $htmlBody .= sprintf('<li>%s (%s)</li>', $playlistItem['snippet']['title'],
                    $playlistItem['snippet']['resourceId']['videoId']);
            }
            $htmlBody .= '</ul>';
        }
    } catch (Google_ServiceException $e) {
        $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
            htmlspecialchars($e->getMessage()));
    } catch (Google_Exception $e) {
        $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
            htmlspecialchars($e->getMessage()));
    }

    $_SESSION['token'] = $client->getAccessToken();
} else {
    $state = mt_rand();
    $client->setState($state);
    $_SESSION['state'] = $state;

    $authUrl = $client->createAuthUrl();
    $htmlBody = <<<END
  <h3>Authorization Required</h3>
  <p>You need to <a href="$authUrl">authorise access</a> before proceeding.<p>
END;
}
?>

<!doctype html>
<html>
<head>
    <title>My Uploads</title>
</head>
<body>
<?php echo $htmlBody?>
</body>
</html>

Once you’ve got the script above and the Google Client Library API in place, load the script in your browser. You should be prompted to Authorise access before you can continue. Once you click on this link you should be taken through the steps to authorise your currently logged in Google account to access your new application.

Once it’s all done you should be redirected back to the localhost page, except now you will see a JSON string along the top of the page. Save this string somewhere for use later on. You might also notice if you’ve already uploaded videos to YouTube, a list of your videos on the page – just to confirm the access token works!

Saving your credentials

Now that you’ve received your refresh tokens create a text file called “the_key.txt” with the following information you’ve just received, it should look something similar to the format below:

{"access_token":"XXXXXXXXX","token_type":"Bearer", "expires_in":3600, "refresh_token":"XXXXXXX", "created":000000}

I suggest you write your refresh token down somewhere for safe keeping.

 

Creating the upload script

The script below is a very basic implementation. It requires the following file structure:

  • Google/
  • upload.php (the script below)
  • the_key.txt (the file we created in the previous section)
  • tutorial.mp4 (the video to upload)

The script will automatically update your “the_key.txt” file if your access_token is out of date.

Set the include path to ensure the Google API works correctly (line 3).

Replace the following variables with your own information:

  • $application_name
  • $client_secrect
  • $client_id
  • $videoPath
  • $videoTitle
  • $videoDescription
  • $videoCategory
  • $videoTags

 

$key = file_get_contents('the_key.txt');

set_include_path($_SERVER['DOCUMENT_ROOT'] . '/path-to-your-director/');
require_once 'Google/Client.php';
require_once 'Google/Service/YouTube.php';

$application_name = 'XXXXXX'; 
$client_secret = 'XXXXXXX';
$client_id = 'XXXXXXX.apps.googleusercontent.com';
$scope = array('https://www.googleapis.com/auth/youtube.upload', 'https://www.googleapis.com/auth/youtube', 'https://www.googleapis.com/auth/youtubepartner');
		
$videoPath = "tutorial.mp4";
$videoTitle = "A tutorial video";
$videoDescription = "A video tutorial on how to upload to YouTube";
$videoCategory = "22";
$videoTags = array("youtube", "tutorial");


try{
	// Client init
	$client = new Google_Client();
	$client->setApplicationName($application_name);
	$client->setClientId($client_id);
	$client->setAccessType('offline');
	$client->setAccessToken($key);
	$client->setScopes($scope);
	$client->setClientSecret($client_secret);

	if ($client->getAccessToken()) {

		/**
		 * Check to see if our access token has expired. If so, get a new one and save it to file for future use.
		 */
		if($client->isAccessTokenExpired()) {
			$newToken = json_decode($client->getAccessToken());
			$client->refreshToken($newToken->refresh_token);
			file_put_contents('the_key.txt', $client->getAccessToken());
		}

		$youtube = new Google_Service_YouTube($client);



		// Create a snipet with title, description, tags and category id
		$snippet = new Google_Service_YouTube_VideoSnippet();
		$snippet->setTitle($videoTitle);
		$snippet->setDescription($videoDescription);
		$snippet->setCategoryId($videoCategory);
		$snippet->setTags($videoTags);

		// Create a video status with privacy status. Options are "public", "private" and "unlisted".
		$status = new Google_Service_YouTube_VideoStatus();
		$status->setPrivacyStatus('private');

		// Create a YouTube video with snippet and status
		$video = new Google_Service_YouTube_Video();
		$video->setSnippet($snippet);
		$video->setStatus($status);

		// Size of each chunk of data in bytes. Setting it higher leads faster upload (less chunks,
		// for reliable connections). Setting it lower leads better recovery (fine-grained chunks)
		$chunkSizeBytes = 1 * 1024 * 1024;

		// Setting the defer flag to true tells the client to return a request which can be called
		// with ->execute(); instead of making the API call immediately.
		$client->setDefer(true);

		// Create a request for the API's videos.insert method to create and upload the video.
		$insertRequest = $youtube->videos->insert("status,snippet", $video);

		// Create a MediaFileUpload object for resumable uploads.
		$media = new Google_Http_MediaFileUpload(
			$client,
			$insertRequest,
			'video/*',
			null,
			true,
			$chunkSizeBytes
		);
		$media->setFileSize(filesize($videoPath));


		// Read the media file and upload it chunk by chunk.
		$status = false;
		$handle = fopen($videoPath, "rb");
		while (!$status && !feof($handle)) {
			$chunk = fread($handle, $chunkSizeBytes);
			$status = $media->nextChunk($chunk);
		}

		fclose($handle);

		/**
		 * Video has successfully been upload, now lets perform some cleanup functions for this video
		 */
		if ($status->status['uploadStatus'] == 'uploaded') {
			// Actions to perform for a successful upload
			// $uploaded_video_id = $status['id'];
		}

		// If you want to make other calls after the file upload, set setDefer back to false
		$client->setDefer(true);

	} else{
		// @TODO Log error
		echo 'Problems creating the client';
	}

} catch(Google_Service_Exception $e) {
	print "Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage();
	print "Stack trace is ".$e->getTraceAsString();
}catch (Exception $e) {
	print "Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage();
	print "Stack trace is ".$e->getTraceAsString();
}

Suggestions

As you can see, the script is very primitive, among other things, this script should not be located in a publicly accessible directory due to the obvious abuse that could occur. In my situation, I created a queue of files to upload and setup a cron to execute the script once an hour that would then check a directory for any files of a certain type (mp4) and then loop through and upload to YouTube. The method I described hasn’t been tested on files more than 10 x 400mb in size so I’m not sure what the impacts would be on your server for more files / larger sizes etc.

Hopefully that’s enough to get your started, if you have any questions feel free to ask :)

Subscribe

You'll only get 1 email per month containing new posts (I hate spam as much as you!). You can opt out at anytime.

Categories

Leave a Reply to Webbho Cancel reply

Your email address will not be published. Required fields are marked *

Preview Comment

52 Comments

  1. Alaa Sadik
    https://www.domsammut.com/?p=1142#comment-1776

    Alaa Sadik

    Very important feedback regarding getting the JSON code
    Please make sure the redirect URI is to the SAME first script “Getting your refresh token” not any other file.
    This solved the problem to me.

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1777

      Dom Sammut

      Hi Alaa,

      Yes, you will need to redirect to the same URI as from where you initiated the authentication to harvest the token.

      Cheers
      Dom

  2. Cliff Fyle
    https://www.domsammut.com/?p=1142#comment-1774

    Cliff Fyle

    Thanks for coding.
    I can’t get the JSON string, just redirected to the callback page, why?
    Appreciated

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1775

      Dom Sammut

      Hi Cliff,

      The JSON string should appear at the top of your callback page :)

      Cheers
      Dom

  3. Alaa Sadik
    https://www.domsammut.com/?p=1142#comment-1767

    Alaa Sadik

    I get this when I try to upload the file, please help:

    Caught Google service Exception 400 message is Error refreshing the OAuth2 token, message: ‘{ “error” : “invalid_request”, “error_description” : “Missing required parameter: refresh_token” }’Stack trace is #0 /home/presen72/public_html/uploadyou3/google-api-php-client/src/Google/Auth/OAuth2.php(272): Google_Auth_OAuth2->refreshTokenRequest(Array) #1 /home/presen72/public_html/uploadyou3/google-api-php-client/src/Google/Client.php(455): Google_Auth_OAuth2->refreshToken(NULL) #2 /home/presen72/public_html/uploadyou3/upload.php(40): Google_Client->refreshToken(NULL) #3 {main}

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1768

      Dom Sammut

      Hi Alaa,

      Please refer to the following comments with the same error message / solution:

      Cheers
      Dom

      • Alaa Sadik
        https://www.domsammut.com/?p=1142#comment-1769

        Alaa Sadik

        Solved, thank you very much!
        The problem is I have to run the first script (Getting your refresh token) one time only then run the upload video script using the saved token. My problem was running the first script many times without updating the token in the saved txt file.
        You done a very great job and you are very helpful.
        Thank you again
        The Founder of PresentationTube.com

        • Dom Sammut
          https://www.domsammut.com/?p=1142#comment-1771

          Dom Sammut

          Hi Alaa,

          Glad to hear you got it all sorted :)

          Cheers
          Dom

  4. Alaa Sadik
    https://www.domsammut.com/?p=1142#comment-1764

    Alaa Sadik

    Is the code above updated to be fully supported by API v3?

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1765

      Dom Sammut

      Hi Alaa,

      This tutorial is using version 3, (version 1.0.5) of the API. I have not updated it to use the latest version, though changes should only be minor.

      Cheers
      Dom

      • Alaa Sadik
        https://www.domsammut.com/?p=1142#comment-1766

        Alaa Sadik

        But not able to overcome this error, please advise.
        Fatal error: Class ‘Google_Service’ not found in /home/presen72/public_html/uploadyou3/google-api-php-client-master/src/Google/Service/YouTube.php on line 32

        • PatrickD
          https://www.domsammut.com/?p=1142#comment-1858

          PatrickD

          You need to include:
          require_once ‘Google/autoload.php’;

  5. rico
    https://www.domsammut.com/?p=1142#comment-1760

    rico

    Hi Dom,

    I have a public ip like the host where i want to upload a video then, i dont know how to use your examples because oauth2 dont permit put a url like http://54.43.23.22 . can i to do this upload using only the API key? how could i do this way?

    sry if my english is a little confuse

    Regards,

    rico

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1761

      Dom Sammut

      Hi Rico,

      Unfortunately that is a requirement of the API. Uploading using an API key was part of YouTube V2 which has been depreciated and no-longer supported. The only method is to use the V3 of the API via OAuth at this point in time :(

      Cheers
      Dom

      • Rico
        https://www.domsammut.com/?p=1142#comment-1795

        Rico

        Hi Dom,

        I solved this problem with a new domain name. But now i can’t refresh the token. I am following this steps to upload a video:
        I load http://mydomain.com/token.php (that contains first of your scripts)

        Then i need to autenticate me and select my gmail and password
        After that i can see the json and list about my uploaded videos

        After I try to upload my video with http://mydomain.com/upload.php (your second script)
        This give me the following error:

        Notice: Undefined variable: array in /srv/www/test/imagestovideo/upload.php on line 21 Notice: Undefined variable: array in /srv/www/test/imagestovideo/upload.php on line 26 Notice: Undefined variable: array in /srv/www/test/imagestovideo/upload.php on line 27 Notice: Undefined property: stdClass::$refresh_token in /srv/www/test/imagestovideo/upload.php on line 50 Caught Google service Exception 400 message is Error refreshing the OAuth2 token, message: ‘{ “error” : “invalid_request”, “error_description” : “Missing required parameter: refresh_token” }’Stack trace is #0 /srv/www/test/googleapi/src/Google/Auth/OAuth2.php(272): Google_Auth_OAuth2->refreshTokenRequest(Array) #1 /srv/www/test/googleapi/src/Google/Client.php(454): Google_Auth_OAuth2->refreshToken(NULL) #2 /srv/www/test/imagestovideo/upload.php(50): Google_Client->refreshToken(NULL) #3 {main}

        Just the token is not refreshing i think
        So I copy-paste manually the json that token.php gives me on the_key.txt and It works fine.

        I can upload videos during 1 hour until the token expires
        After that i have to repeat the process…

        I dont know if my OAuth setting are OK

        redirect URI : http://mydomain.com/token.php
        JavaScriptOrigin: http://mydomain.com

        I dont understand the most of code or explanations but I need to do this, will be great !

        Thank you anyway for this blog
        And sry for my poor english

        Regards,

        Rico

      • rico
        https://www.domsammut.com/?p=1142#comment-1796

        rico

        Hi Dom,

        I had follow your advaices whit the same problem like others users and i have got it !
        It works fine now!!

        Thank you , this blog is amazing :)

        • Dom Sammut
          https://www.domsammut.com/?p=1142#comment-1797

          Dom Sammut

          Glad to hear you got it all working Rico.

          Cheers
          Dom

          • rico
            https://www.domsammut.com/?p=1142#comment-1798

            rico

            Hi again Dom,

            Now I am trying to set thumbnail to video following this:

            https://developers.google.com/youtube/v3/docs/thumbnails/set#examples

            The php example contains all this:

            <?php
            
            /**
             * This sample uploads and sets a custom thumbnail for a video.
             *
             * 1. It uploads an image using the "Google_MediaFileUpload" class.
             * 2. It sets the uploaded image as a custom thumbnail to the video by
             *    calling the API's "youtube.thumbnails.set" method
             *
             * @author Ibrahim Ulukaya
            */
            
            
            // Call set_include_path() as needed to point to your client library.
            require_once 'Google/Client.php';
            require_once 'Google/Service/YouTube.php';
            session_start();
            
            /*
             * You can acquire an OAuth 2.0 client ID and client secret from the
             * Google Developers Console 
             * For more information about using OAuth 2.0 to access Google APIs, please see:
             * 
             * Please ensure that you have enabled the YouTube Data API for your project.
             */
            $OAUTH2_CLIENT_ID = 'REPLACE_ME';
            $OAUTH2_CLIENT_SECRET = 'REPLACE_ME';
            
            $client = new Google_Client();
            $client->setClientId($OAUTH2_CLIENT_ID);
            $client->setClientSecret($OAUTH2_CLIENT_SECRET);
            $client->setScopes('https://www.googleapis.com/auth/youtube');
            $redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
                FILTER_SANITIZE_URL);
            $client->setRedirectUri($redirect);
            
            // Define an object that will be used to make all API requests.
            $youtube = new Google_Service_YouTube($client);
            
            if (isset($_GET['code'])) {
              if (strval($_SESSION['state']) !== strval($_GET['state'])) {
                die('The session state did not match.');
              }
            
              $client->authenticate($_GET['code']);
              $_SESSION['token'] = $client->getAccessToken();
              header('Location: ' . $redirect);
            }
            
            if (isset($_SESSION['token'])) {
              $client->setAccessToken($_SESSION['token']);
            }
            
            // Check to ensure that the access token was successfully acquired.
            if ($client->getAccessToken()) {
              try{
            
                // REPLACE this value with the video ID of the video being updated.
                $videoId = "VIDEO_ID";
            
                // REPLACE this value with the path to the image file you are uploading.
                $imagePath = "/path/to/file.png";
            
                // Specify the size of each chunk of data, in bytes. Set a higher value for
                // reliable connection as fewer chunks lead to faster uploads. Set a lower
                // value for better recovery on less reliable connections.
                $chunkSizeBytes = 1 * 1024 * 1024;
            
                // Setting the defer flag to true tells the client to return a request which can be called
                // with ->execute(); instead of making the API call immediately.
                $client->setDefer(true);
            
                // Create a request for the API's thumbnails.set method to upload the image and associate
                // it with the appropriate video.
                $setRequest = $youtube->thumbnails->set($videoId);
            
                // Create a MediaFileUpload object for resumable uploads.
                $media = new Google_Http_MediaFileUpload(
                    $client,
                    $setRequest,
                    'image/png',
                    null,
                    true,
                    $chunkSizeBytes
                );
                $media->setFileSize(filesize($imagePath));
            
            
                // Read the media file and upload it chunk by chunk.
                $status = false;
                $handle = fopen($imagePath, "rb");
                while (!$status && !feof($handle)) {
                  $chunk = fread($handle, $chunkSizeBytes);
                  $status = $media->nextChunk($chunk);
                }
            
                fclose($handle);
            
                // If you want to make other calls after the file upload, set setDefer back to false
                $client->setDefer(false);
            
            
                $thumbnailUrl = $status['items'][0]['default']['url'];
                $htmlBody .= "Thumbnail Uploaded";
                $htmlBody .= sprintf('%s (%s)',
                    $videoId,
                    $thumbnailUrl);
                $htmlBody .= sprintf('', $thumbnailUrl);
                $htmlBody .= '';
            
            
                } catch (Google_ServiceException $e) {
                  $htmlBody .= sprintf('A service error occurred: %s',
                      htmlspecialchars($e->getMessage()));
                } catch (Google_Exception $e) {
                  $htmlBody .= sprintf('An client error occurred: %s',
                      htmlspecialchars($e->getMessage()));
                }
            
                $_SESSION['token'] = $client->getAccessToken();
                } else {
                  // If the user hasn't authorized the app, initiate the OAuth flow
                  $state = mt_rand();
                  $client->setState($state);
                  $_SESSION['state'] = $state;
            
                  $authUrl = $client->createAuthUrl();
                  $htmlBody = <<<END
              Authorization Required
              You need to authorize access before proceeding.
            END;
                }
                ?>
            

            Claim Uploaded

            I don’t know how to apply this. I change the require_onces

            require_once ‘/srv/www/test/googleapi/src/Google/autoload.php’;
            require_once ‘/srv/www/test/googleapi/src/Google/Client.php’;
            require_once ‘/srv/www/test/googleapi/src/Google/Service/YouTube.php’;

            And I put mi client ID and secret and my videoID and image that i want like new thumbnail
            Could you help with that?

            My scripst returns me page blank but returns me any echo write into
            else {
            // If the user hasn’t authorized the app, initiate the OAuth flow
            echo “hello world”;
            $state = mt_rand();
            $client->setState($state);
            $_SESSION[‘state’] = $state;

            $authUrl = $client->createAuthUrl();
            $htmlBody = <<<END
            Authorization Required
            You need to authorize access before proceeding.
            END;
            }

            Regards,

            rico

            • Dom Sammut
              https://www.domsammut.com/?p=1142#comment-1800

              Dom Sammut

              Hi Rico,

              This is not part of the tutorial so I won’t be able to help you out with this. Sufficed to say, this should be relatively similar to implementing video uploads to YouTube.

              You’ll need to read in your refresh token as you need to do when you upload your video as per this tutorial. The tutorial you’re following is assuming you’ve already authenticated.

              Goodluck,
              Dom

  6. Sudarmono
    https://www.domsammut.com/?p=1142#comment-1758

    Sudarmono

    Hi Dom,
    your code work fine,
    but i need help,
    how to replace access token automaticlly if upload.php was accessed from other account?

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1759

      Dom Sammut

      Hi Sudarmono,

      I’ll need a little bit more information to provide a solid answer, namely, how is upload.php accessed by a different account (are you referring to server side access?)? If it’s a different account you’re uploading to you’ll need to create a new project inside that account as you can only upload to accounts you own. I’d recommend storing any additional refresh tokens harvested during the auth process to facilitate multi-account access.

      Cheers
      Dom

      Cheers
      Dom

  7. Cookie Monster
    https://www.domsammut.com/?p=1142#comment-1755

    Cookie Monster

    Hi!

    Can you suggest how to retrieve uploaded video’s URL right after uploading?

  8. saad
    https://www.domsammut.com/?p=1142#comment-1747

    saad

    hi Dom
    i follow the tutorial step and i click on authorise access it show me my project i click on accpet then it redirect me to my redirect url which i add. but as u said in tutorial that i will find JSON string along the top of the page. but it was not in my page
    please help

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1748

      Dom Sammut

      Hi Saad,

      Can you confirm you’re using version 1.0.5 of the API? Can you also view source of the page to confirm you can’t see the JSON output at the very top of the page. As a second step, can you reset and try again from scratch. A couple of other people who have posted comments on this post stated after doing this they were able to successfully harvest a token.

      Let me know how you go.

      Cheers
      Dom

      • saad
        https://www.domsammut.com/?p=1142#comment-1751

        saad

        Hi
        yes i download the fresh version 1.0.5 of the API
        i see the error log it show error of missing class but that class was exist when i include that class using include() then it show error of missing another class when i include that one then it shows and other missing class. i think the file having classes is not auto including

        • Dom Sammut
          https://www.domsammut.com/?p=1142#comment-1752

          Dom Sammut

          Hi Saad,

          It sounds like you haven’t set the correct directory location for set_include_path(). You should only need to require_once() two files:

          • Google/Client.php
          • Google/Service/YouTube.php

          Cheers
          Dom

          • saad
            https://www.domsammut.com/?p=1142#comment-1753

            saad

            HI
            can you please guide me how i can do it
            thanks in advance

            • Dom Sammut
              https://www.domsammut.com/?p=1142#comment-1754

              Dom Sammut

              Hi Saad,

              Basic PHP is not covered in this tutorial. I suggest you read the set_include_path function in the PHP documentation.

              Cheers
              Dom

  9. Loredana
    https://www.domsammut.com/?p=1142#comment-1745

    Loredana

    Hello, I tried to follow your tutorial but I obtain Exception 0 “Could not json decode the token”.
    Can you help me to solve it? Thanks.
    Regards,
    Loredana

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1746

      Dom Sammut

      Hi Loredana,

      Can you confirm the contents of your “the_key” file as well as just doing a var_dump() of its contents in your script to confirm you have the correct file permissions so that PHP can read it.

      Cheers
      Dom

      • Loredana
        https://www.domsammut.com/?p=1142#comment-1749

        Loredana

        Hi Dom,
        yes, I solved giving right permissions to “the_key.txt”.
        Thanks,
        Loredana

  10. fazal
    https://www.domsammut.com/?p=1142#comment-1736

    fazal

    hi Dom
    i run thi script on local host 1st it show error that Google/Client.php and youtube.php is not found
    then i add the files now it show that the Google_Service’ not found
    then i run it on web but it show no error but showing blank page
    Please help

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1737

      Dom Sammut

      Hi Fazal,

      First, ensure you’re using version 1.0.5 of the Google PHP API.

      Secondly, the fact that you see a blank page indicates you must not be including the correct files, resulting in the page not being rendered. As you’ll note in Getting your refresh token, if you have not authorised your app, it will display a message saying so, otherwise it will display a list of videos from your YouTube channel.

      Cheers
      Dom

      • fazal
        https://www.domsammut.com/?p=1142#comment-1738

        fazal

        yes i using 1.0.5 of the Google PHP API. i include all the files shown in the link.
        2nd let main conform am i upload videos to your tube in my account.. ?

      • fazal
        https://www.domsammut.com/?p=1142#comment-1739

        fazal

        HI DOM
        Yes i am using the same file show in link 1.0.5 of the Google PHP API.
        let me explain steps which follow
        1 i create the project
        2 create the directory in my webserver and add index.php file and add the code shown above
        and add my client id and secret code in APPNAME i enter project name.

        • Dom Sammut
          https://www.domsammut.com/?p=1142#comment-1741

          Dom Sammut

          Hi Fazal,

          When you view the source of the index.php file in your web browser, what do you see?

          Cheers
          Dom

          • fazal
            https://www.domsammut.com/?p=1142#comment-1742

            fazal

            it show Just head tag and body tag. it create error log which show that ‘Google_Service’ not found in /home6/imperif7/public_html/youtube/Google/Service/YouTube.php on line 31
            in line No# 31 of youtube.php i found the https://www.googleapis.com/auth/youtube link when i open this link in my browser it show only youtube. in bold

            • Dom Sammut
              https://www.domsammut.com/?p=1142#comment-1744

              Dom Sammut

              Hi Fazal,

              First off, please understand that I have other commitments and response to comments on my blog are not always quick, nor my first priority. Making additional comments (that have been removed, as they are not useful) prompting me for response will not be tolerated, this is a warning.

              In regards to your issue, Line 31 of YouTube.php file is not that link, its the line before the class declaration. If you read the error message you provided me “‘Google_Service’ not found in …“, it states the parent class, Google_Serivce is not found. Meaning the Google_Service_Youtube is attempting to extend on a class it cannot find. I would suggest you check your files to ensure that everything is in order.

              Ideally, wipe your Google PHP API download and start fresh, ensuring that you have set all the correct include paths.

              Cheers
              Dom

  11. Edmon Dantes
    https://www.domsammut.com/?p=1142#comment-1735

    Edmon Dantes

    Hi Dom,

    To day, I start your toturial again, and amazing, it work fine! Thank you for nice toturial.

    Cheers
    Edmon Dantes

  12. Edmon Dantes
    https://www.domsammut.com/?p=1142#comment-1732

    Edmon Dantes

    Hi Dom,

    I delete all my old project and create new project, and start toturial again, but received same error. Any idea to help me?

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1733

      Dom Sammut

      Hi Edmon,

      If you’re using the code in my tutorial exactly and just replacing the variables, it sounds like a setup issue, ensure you’ve followed all steps in the Creating Your Project section.

      I can’t provide much more assistance than what I already have, unless you have error logs or links to screenshots.

      Can you confirm you are able to harvest the refresh_token in the first place. I note, in your initial post you received an error when attempting to upload a video. Do not attempt to debug the video upload process until you can confirm you have a valid refresh token, otherwise the process will not work.

      Cheers
      Dom

  13. Edmon Dantes
    https://www.domsammut.com/?p=1142#comment-1728

    Edmon Dantes

    Hi Dom.
    When i getting refresh token, i received
    {“access_token”:”xxxxxxxxxxxxxxxxxxxx”,”token_type”:”Bearer”,”expires_in”:3600,”created”:1425813528}

    An client error occurred: The OAuth 2.0 access token has expired, and a refresh token is not available. Refresh tokens are not returned for responses that were auto-approved.

    And when i upload my videos, i received:
    Caught Google service Exception 400 message is Error refreshing the OAuth2 token, message: ‘{ “error” : “invalid_request”, “error_description” : “Missing required parameter: refresh_token” }’Stack trace is #0 C:\AppServ\www\Google\Auth\OAuth2.php(272): Google_Auth_OAuth2->refreshTokenRequest(Array) #1 C:\AppServ\www\Google\Client.php(454): Google_Auth_OAuth2->refreshToken(NULL) #2 C:\AppServ\www\upload.php(38): Google_Client->refreshToken(NULL) #3 {main}

    Can you fix it to me?

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1729

      Dom Sammut

      Hi Edmon,

      It appears you don’t have a refresh token in your request which is why it’s failing. You’ll need to unlink your application and re-harvest the access token and ensure you save this in a place that is accessible by your script so it can be used in all API communication.

      Cheers
      Dom

      • Edmon Dantes
        https://www.domsammut.com/?p=1142#comment-1730

        Edmon Dantes

        Hi Dom.
        I don’t known how to unlink your application and re-harvest the access token. Can you guide me. I delete old client id and create new client it, but same error display.

        • Dom Sammut
          https://www.domsammut.com/?p=1142#comment-1731

          Dom Sammut

          Hi Edmon,

          The easiest way is just to delete it in the developer console and start again, basically, restart the tutorial. Ensure that when you save the credentials in the “the_key.txt” that it contains the refresh token.

          Cheers
          Dom

  14. Matteo
    https://www.domsammut.com/?p=1142#comment-1721

    Matteo

    Hello Dom, i arrived at the page where “Youtube would be manage your account”, i press accept but then it don’t find the page of redirect, in fact it shows “The web page is not available”. Redirect uris is automatic so i can’t do anything..? thank you

    • Dom Sammut
      https://www.domsammut.com/?p=1142#comment-1722

      Dom Sammut

      Hi Matteo,

      I’m guessing from what you’ve said you’re attempting to harvest a refresh token? If this is the case, ensure that $REDIRECT = 'http://localhost/oauth2callback.php'; is set to the path of your harvest script.

      Can you confirm you’ve set this value to the harvest script?

      Cheers
      Dom

      • Matteo
        https://www.domsammut.com/?p=1142#comment-1724

        Matteo

        Yes, this is my authorized javascript origins: promotools.it , so automatically my auth redirect uris is promotools.it/oauth2callback , but it tells “page not found”

        • Dom Sammut
          https://www.domsammut.com/?p=1142#comment-1725

          Dom Sammut

          Hi Matteo,

          Is the 404 error on your website? Where are you calling the script from? The URL you’ve provided for the oauth2callback page doesn’t exist. The script needs to redirect you to the page you executed the script from. What is the URL your executing the script from? That URL should be what you set the redirect to.

          Cheers
          Dom

          • matteo
            https://www.domsammut.com/?p=1142#comment-1726

            matteo

            Oh i’ve just found that website must have secure protocol, so they don’t accept requests from http but only from https

css.php