How to Authenticate & upload videos to YouTube Channel in PHP
Tips & Tricks 24-Sep-2016

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.

Setting up the environment

Step 1.

Go to Google’s Developer Console (

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


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.

//ini_set("display_errors", 'off'); //remove when not live
$videoName = 'linkedin.mp4';
$format = strtolower(array_pop(explode(".", $videoName)));


<html lang="en">
<meta charset="UTF-8">
<script src=""></script>
<link rel="stylesheet" href="//"/>
<script src="//"></script>
<title>Upload Video to Your Youtube Account</title>
<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">
<video controls>
<source src="videos/<?php echo $videoName; ?>" type="video/<?php echo $format; ?>">
Your browser does not support HTML5 Videos

    $(function() {



// Call set_include_path() as needed to point to your client library.
require_oncedirname(__FILE__). DIRECTORY_SEPARATOR .'API'
require_oncedirname(__FILE__).  DIRECTORY_SEPARATOR .'API'

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


We set up the client id and the secret key.


$client = new Google_Client();
//redirect to the same page
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],

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

    $_SESSION['token'] = $client->getAccessToken();
header('Location: ' . $redirect);

if (isset($_SESSION['token'])) {

We authenticate the user with his YouTube account.

if($client->getAccessToken()) {
// 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:");
        $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();

// 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.

// 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(

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


// If you want to make other calls after the file upload, set setDefer back to 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

} catch (Google_ServiceException $e) {
    $htmlBody.= sprintf('<p>A service error occurred: <code>%s</code></p>',
} catch (Google_Exception $e) {
    $htmlBody.= sprintf('<p>An client error occurred: <code>%s</code></p>',

$_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();
    $_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 class="modal-body">
<p>You need to login to Youtube in order to upload that video.</p>
<div class="modal-footer">
<button type="button" class="btnbtn-default" data-dismiss="modal">Close</button>
<a href="$authUrl" class="btnbtn-primary">Proceed</a>



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