February 26, 2015 9:47 am

How to Authenticate & upload videos to YouTube Channel in PHP

We have received many requests from our readers to write tutorial on YouTube video uploading using data API, so today we are going to show you in this tutorial that how you can authenticate and upload videos on your YouTube channel in PHP. Basically we used YouTube Data API v3 in PHP and its very easy to configure demo and download source freely available.

How to Authenticate & upload videos to YouTube Channel in PHP

[wpdm_file id=128]DEMO

Setting up the environment

Step 1.

Go to Google’s Developer Console (https://console.developers.google.com/project)

Setting up the environment

 

Step 2.

Create a project

Setting up the environment 1

Step 3.

Open that project and click on Enable an API

Setting up the environment Enable API

Step 4.

Search for Youtube Data API v3 and turn it on (You could turn YouTube Data API on from APIs &auth -> APIs as well)

Setting up the environment enable youtube data API v3

Setting up the environment enable youtube data API v3 enabled

Step 5.

Go to Credentials under APIs and Create new Client ID

Setting up the environment API Credentials

Step 6.

Select client id application type

Setting up the environment API Credentials website

Step 7.

Write details for application

Setting up the environment API Credentials setup

Step 8.

Set up the JavaScript origins (websites that could access the API with your credentials). Do not forget to set up the REDIRECT URIs which should contain the full path to the page that is going to serve the API. You delimit different pages by new line (enter).

Setting up the environment API Credentials setup javascript origins

Step 9.

Use the CLIENT ID and CLIENT SECRET in the api.php file (replace $OAUTH2_CLIENT_ID with a string containing your client id and $OAUTH2_CLIENT_SECRET with a string containing your secret key.

Setting up the environment API Credentials copy

This app actually makes use of the Google’s API PHP client which is included along with the app itself in the downloads page.

Actual app

Index.php

In the index we disable displaying errors and set the maximum execution time to 2 minutes (video uploads require more time than usual and the request may time out if the maximum execution time is low).

We set the video name and deduce the file format from that name. We have done this in order to show you how you can upload to users accounts different videos only by changing the $videoName variable (the app assumes they are stored in ‘videos’ directory relative to index.php)

We load api.php which is going to display modal urging users to authenticate with YouTube and will immediately start uploading then.

Towards the end, we display the name of the file that would be uploaded to the user’s account and add a video tag that renders the video in order for visitors to be certain they want this video.

<?php
session_start();
//ini_set("display_errors", 'off'); //remove when not live
set_time_limit(120);
$videoName = 'linkedin.mp4';
$format = strtolower(array_pop(explode(".", $videoName)));
require_once('api.php');

?>

<!doctypehtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<title>Upload Video to Your Youtube Account</title>
</head>
<body>
<h1 class="text-center">You are attempting to upload the file: <span class="label label-warning"><?php echo $videoName; ?></span></h1>

<div class="text-center jumbotron col-md-6 col-md-offset-3">
<h1>Preview:</h1>
<video controls>
<source src="videos/<?php echo $videoName; ?>" type="video/<?php echo $format; ?>">
Your browser does not support HTML5 Videos

</video>
</div>
<script>
    $(function() {
        $(".modal").modal("show");

    })
</script>
</body>
</html>

api.php

// Call set_include_path() as needed to point to your client library.
require_oncedirname(__FILE__). DIRECTORY_SEPARATOR .'API'
.DIRECTORY_SEPARATOR .'src' . DIRECTORY_SEPARATOR .'Google' .
DIRECTORY_SEPARATOR .'Client.php';
require_oncedirname(__FILE__).  DIRECTORY_SEPARATOR .'API'
.DIRECTORY_SEPARATOR .'src' . DIRECTORY_SEPARATOR .'Google' .
DIRECTORY_SEPARATOR .'Service' .DIRECTORY_SEPARATOR .
'YouTube.php';

We load the Google’s API PHP client files in an OS-independent way and start the session.

$OAUTH2_CLIENT_ID = 'YOUR_CLIENT_ID';
$OAUTH2_CLIENT_SECRET = 'YOUR_SECRET_KEY';

We set up the client id and the secret key.

Api.php

$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
//redirect to the same page
$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']);
}

We authenticate the user with his YouTube account.

if($client->getAccessToken()) {
try{
// REPLACE this value with the path to the file you are uploading.
$videoPath= "videos" .DIRECTORY_SEPARATOR .$videoName;

// Create a snippet with title, description, tags and category ID
        // Create an asset resource and set its snippet metadata and type.
        // This example sets the video's title, description, keyword tags, and
        // video category.
$snippet = new Google_Service_YouTube_VideoSnippet();
        $snippet->setTitle("How to publish status on linkedin in PHP");
        $snippet->setDescription("tutorial going to solve your problems and its very easy to publish status on your LinkedIn wall. No need to go to LinkedIn and update your status from your website create a file on your web site which do this all stuff without going to LinkedIn. To get Code to do as we are doing in this video follow this link: https://www.phpgang.com/post-auto-status-on-linkedin-with-php_511.html");
        $snippet->setTags(array("LinkedIn status", "PHP", "LinkedIn", "oauth"));
$snippet->setCategoryId("27"); //category - education

If he is successfully authenticated, we set up the path to the video that we are going to upload for him and set metadata about the video (title, description and tags) and set up the category of the video

$status = new Google_Service_YouTube_VideoStatus();
    $status->privacyStatus= "public"; //public,private or unlisted

    // Associate the snippet and status objects with a new video resource.
$video = new Google_Service_YouTube_Video();
    $video->setSnippet($snippet);
    $video->setStatus($status);

// 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 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);

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


    $htmlBody= "<h1 class='alert alert-success text-center'>Video $videoName Uploaded</h3><ul>";
//destroying the session to prevent users fromreuploading the video if they refresh or go back
session_destroy();

} 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();

We send the actual video in chunks, enable resumable uploads and display the success text or the type of service/client error, if any.

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
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Authorization Required</h4>
</div>
<div class="modal-body">
<p>You need to login to Youtube in order to upload that video.</p>
</div>
<div class="modal-footer">
<button type="button" class="btnbtn-default" data-dismiss="modal">Close</button>
<a href="$authUrl" class="btnbtn-primary">Proceed</a>
</div>
</div>
</div>
</div>

END;
}
?>


<?=$htmlBody?>

If the user has not yet given authorization to the app, we add the modal to the DOM.

References:

  1. Creative Commons Video downloaded from: http://youtu.be/ejjFWxPInGU
  2. Original Youtube Data API example: https://developers.google.com/youtube/v3/docs/videos/insert

Author Ivan Dimov

Ivan is a student of IT, a freelance web designer/developer and a tech writer. He deals with both front-end and back-end stuff. Whenever he is not in front of an Internet-enabled device he is probably reading a book or traveling. You can find more about him at: http://www.dimoff.biz. facebook, twitter


Tutorial Categories:

15 responses to “How to Authenticate & upload videos to YouTube Channel in PHP”

  1. Mark Bagnall says:

    Would be great to show from user selecting a video in a html form

  2. popular design says:

    it’s to easy step, thank-you for sharing.

  3. Awesome… thank you! it works! BTW, where is the api.php file?

  4. Deepak Chandra Pandey says:

    could anyone tell me how to get refresh token , I have uploaded video on youtube using php after one hr the script giving me this error

    “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.”

    Please tell me how to get refresh token

  5. kekotamu says:

    How to make progress bar upload in this script?
    and how make a multiple upload?

  6. Trang Hoàng says:

    not download???

  7. Trang Hoàng says:

    not download???

  8. nick says:

    i keep getting the authorization required message even after i am sent to youtube and confirmed everything. i get sent back to my page but authorization request shows up again and again

  9. nick says:

    oh nevermind, it is working. the videos are being uploaded even though i get the error message.

  10. sanjay says:

    how could I run script on cron job where we can’t authenticate account? I was previously doing with zend gdata library

  11. Gil Palikaras says:

    Hello, I tried using this implementation (btw, works much better than the one in the official documentation!) but I am stuck in a very specific point:
    After I get the message that my video is uploaded, in the Video Manager page of my YouTube account I see the video, but the status message below it is “0% uploaded” and it stays like this.

    Also, I had to make a change to the code at line 22 to this:

    $media = new Google_Http_MediaFileUpload(
    $client,
    $insertRequest,
    ‘video/*’,
    file_get_contents($videoPath),
    true,
    $chunkSizeBytes
    );

    Before that, with the original code, I got the message “Preparing upload.” (also stayed like this).
    I did change the credentials (client ID and Client Secret) to mine.

    Do you know what might be the reason that the upload can’t be completed?

    Thank you

  12. Dhirendra Bisht says:

    Hi I am getting two errors 1st Its showing authorization popup in place of success message every time .

    And script working only once for one account 🙁 its realy urgent for me Thanks in advance for any suggestion This is my link http://jasonallan.work/videomaker/youtube/

  13. Faizan Zahid says:

    Kindly update the blog with the directory structure of application so that some novice developer may find ease to understand it

Leave a Reply

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