How to use YouTube API to Upload Video on YouTube Channel

Everybody knows about YouTube. YouTube is the number one video-sharing platform in the world. The YouTube platform allows us to host our videos. This saves us a lot of server space and one can easily embed the video from YouTube on their website. Anyone can upload the video on YouTube. You just need to create your YouTube account and upload the video. Simple and straightforward process. But what if someone needs to upload videos through the YouTube API on a YouTube channel? Is it possible? Yes, it is possible. In this article, we study how to use the YouTube API to upload a video using PHP.

Register the Application and Create Credentials

To get started with the YouTube API, you need a Google Account. Once you have a Google account register your application and get the API keys.

Below are the steps to register an application and get your API keys.

  • Go to the Google Developer Console https://console.developers.google.com.
  • Create a new project. You can select existing projects also.
  • Type a name of your project. Google Console will create a unique project ID.
  • After creating a project, it will appear on top of the left sidebar.
  • Click on Library. You will see a list of Google APIs.
  • Enable YouTube Data API.
  • Click on the Credentials. Select Oauth Client id under Create credentials. Select the radio button for Web Application.
  • Give the Name. Under Authorized JavaScript origins enter your domain URL. In the Authorized redirect URIs give the link of the redirect URL. In my case I passed the URL http://localhost/youtube/callback.php.
  • Click on the Create button. You will get client ID and client secret in the pop-up. Copy these details. We will need it in a moment.
Google Credentials

Setup a Basic Configuration

Uploading video using the YouTube API requires you to create an access token. An access token is nothing but an identifier of your YouTube account.

But, the access token expires after some time passes. The expired access token throws the error of ‘Unauthorized access’. The solution for this is to run the authorization process again or regenerate the access token in the background. In this article, I go for a second solution. We will regenerate the access token if it expires in the background without breaking the uploading process. By doing so, you don’t need to do the authorization process again and again.

For this, you need to first authorize the account to generate an access token. I am going to use the Hybridauth library for authorization and to generate the access token. Open your composer.json file and add the below lines in it.

{
    "require": {
        "google/apiclient": "^2.10",
        "hybridauth/hybridauth" : "~3.0"
    },
    "scripts": {
        "pre-autoload-dump": "Google\\Task\\Composer::cleanup"
    },
    "extra": {
        "google/apiclient-services": [
            "YouTube"
        ]
    }
}

Keep a note YouTube is Google’s product and YouTube API is nothing but a Google API. That’s why we are using the “google/apiclient” library. There are over 200 Google API services and we need only ‘YouTube’ service. So I used Google\Task\Composer::cleanup task to clean up and kept only the ‘YouTube’ service.

Next, run the command below for the installation of libraries.

composer install

Database Configuration

On each API call, we need to send an access token. So it should be stored in the database. Create a table ‘youtube_oauth’ in your database using the below query.

CREATE TABLE `youtube_oauth` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `provider` varchar(255) NOT NULL,
 `provider_value` text NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

We will need to interact with this ‘youtube_oauth’ table for fetching and updating token details. That requires writing a database connection and a few queries. Create a file class-db.php and add the following code to it.

class-db.php

<?php
class DB {
    private $dbHost     = "DB_HOST";
    private $dbUsername = "DB_USERNAME";
    private $dbPassword = "DB_PASSWORD";
    private $dbName     = "DB_NAME";
 
    public function __construct(){
        if(!isset($this->db)){
            // Connect to the database
            $conn = new mysqli($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbName);
            if($conn->connect_error){
                die("Failed to connect with MySQL: " . $conn->connect_error);
            }else{
                $this->db = $conn;
            }
        }
    }
 
    public function is_table_empty() {
        $result = $this->db->query("SELECT id FROM youtube_oauth WHERE provider = 'youtube'");
        if($result->num_rows) {
            return false;
        }
 
        return true;
    }
 
    public function get_access_token() {
        $sql = $this->db->query("SELECT provider_value FROM youtube_oauth WHERE provider = 'youtube'");
        $result = $sql->fetch_assoc();
        return json_decode($result['provider_value']);
    }
 
    public function get_refersh_token() {
        $result = $this->get_access_token();
        return $result->refresh_token;
    }
 
    public function update_access_token($token) {
        if($this->is_table_empty()) {
            $this->db->query("INSERT INTO youtube_oauth(provider, provider_value) VALUES('youtube', '$token')");
        } else {
            $this->db->query("UPDATE youtube_oauth SET provider_value = '$token' WHERE provider = 'youtube'");
        }
    }
}

Pass your database credentials in the above file. Here I have defined different methods which will fetch, insert, and update the tokens.

Generate Access Token for YouTube API

You have installed the libraries and created a table for storing the token. Now let’s write the code which will perform the authorization process, grab the access token, and store it in the ‘youtube_oauth’ table.

Create a config.php file and write a configuration as per the guidelines of the HybridAuth library.

config.php

<?php
require_once 'vendor/autoload.php';
require_once 'class-db.php';
 
define('GOOGLE_CLIENT_ID', 'PASTE_CLIENT_ID_HERE');
define('GOOGLE_CLIENT_SECRET', 'PASTE_CLIENT_SECRET_HERE');
 
$config = [
    'callback' => 'YOUR_DOMAIN_URL/callback.php',
    'keys'     => [
                    'id' => GOOGLE_CLIENT_ID,
                    'secret' => GOOGLE_CLIENT_SECRET
                ],
    'scope'    => 'https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload',
    'authorize_url_parameters' => [
            'approval_prompt' => 'force', // to pass only when you need to acquire a new refresh token.
            'access_type' => 'offline'
    ]
];
 
$adapter = new Hybridauth\Provider\Google( $config );

Replace the placeholders with the actual values of your Google credentials. Add the same callback URL which you passed while creating the console application. When the user completes the authorization process they will redirect to the callback.php file.

In callback.php file, we will fetch the access token details and store them in the database.

callback.php

<?php
require_once 'config.php';
 
try {
    $adapter->authenticate();
    $token = $adapter->getAccessToken();
    $db = new DB();
    $db->update_access_token(json_encode($token));
    echo "Access token inserted successfully.";
}
catch( Exception $e ){
    echo $e->getMessage() ;
}

Head over to your browser and run YOUR_DOMAIN_URL/callback.php, you will redirect to the Google account, complete the authorization process and you should see the success message. Check the database table ‘youtube_oauth’. It should have your token details stored. And that means you are good to go ahead to upload a video on your YouTube channel.

Upload Video on YouTube Channel using YouTube API

You got the access token required for uploading the video on the YouTube channel. But as I mentioned before, the access token will expire after some time and we will regenerate it in the background without asking for authorization again.

We can do it using ‘refersh_token’. If you look at the ‘provider_value’ column in the table you will see it also contains the entry of ‘refresh_token’. Using this ‘refresh_token’ we call the ‘/o/oauth2/token’ endpoint and regenerate the access token in the background.

Next, create the HTML form to browse the video and send it to the server for uploading. Let’s create a simple HTML form as follows.

index.php

<form method="post" enctype="multipart/form-data">
    <p><input type="text" name="title" placeholder="Enter Video Title" /></p>
    <p><textarea name="summary" cols="30" rows="10" placeholder="Video description"></textarea></p>
    <p><input type="file" name="file" /></p>
    <input type="submit" name="submit" value="Submit" />
</form>

The form has 3 fields – title, description, and file. On submission of this form, the below code will upload your video on the YouTube channel along with the title and description.

index.php

<?php
require_once 'config.php';
 
if (isset($_POST['submit'])) {
    $arr_data = array(
        'title' => $_POST['title'],
        'summary' => $_POST['summary'],
        'video_path' => $_FILES['file']['tmp_name'],
    );
    upload_video_on_youtube($arr_data);
}
 
function upload_video_on_youtube($arr_data) {
 
    $client = new Google_Client();
 
    $db = new DB();
 
    $arr_token = (array) $db->get_access_token();
    $accessToken = array(
        'access_token' => $arr_token['access_token'],
        'expires_in' => $arr_token['expires_in'],
    );
 
    $client->setAccessToken($accessToken);
 
    $service = new Google_Service_YouTube($client);
 
    $video = new Google_Service_YouTube_Video();
 
    $videoSnippet = new Google_Service_YouTube_VideoSnippet();
    $videoSnippet->setDescription($arr_data['summary']);
    $videoSnippet->setTitle($arr_data['title']);
    $video->setSnippet($videoSnippet);
 
    $videoStatus = new Google_Service_YouTube_VideoStatus();
    $videoStatus->setPrivacyStatus('public');
    $video->setStatus($videoStatus);
 
    try {
        $response = $service->videos->insert(
            'snippet,status',
            $video,
            array(
                'data' => file_get_contents($arr_data['video_path']),
                'mimeType' => 'video/*',
                'uploadType' => 'multipart'
            )
        );
        echo "Video uploaded successfully. Video ID is ". $response->id;
    } catch(Exception $e) {
        if( 401 == $e->getCode() ) {
            $refresh_token = $db->get_refersh_token();
 
            $client = new GuzzleHttp\Client(['base_uri' => 'https://accounts.google.com']);
 
            $response = $client->request('POST', '/o/oauth2/token', [
                'form_params' => [
                    "grant_type" => "refresh_token",
                    "refresh_token" => $refresh_token,
                    "client_id" => GOOGLE_CLIENT_ID,
                    "client_secret" => GOOGLE_CLIENT_SECRET,
                ],
            ]);
 
            $data = (array) json_decode($response->getBody());
            $data['refresh_token'] = $refresh_token;
 
            $db->update_access_token(json_encode($data));
 
            upload_video_on_youtube($arr_data);
        } else {
            //echo $e->getMessage(); //print the error just in case your video is not uploaded.
        }
    }
}
?>

The above code takes a video file from the HTML form and uploads it through API on your YouTube channel. If your access token has expired then it regenerates the token in the background and continues the process without breaking it.

Upload a Custom Thumbnail on YouTube Video

If you are building a custom application that manages YouTube videos then probably you are looking to upload a thumbnail for a YouTube video. Uploading a custom thumbnail requires users to verify their phone number with their YouTube account. Visit the link https://www.youtube.com/features and do the phone number verification.

Once you verified the phone number, you can use our previous form and code with little modifications and set the custom thumbnail for the uploaded video. First, add the form field which allows uploading images. The recommended YouTube thumbnail size is 1280x720.

<p>
    <label>Image</label>
    <input type="file" name="image" accept="image/*" />
</p>

On the form submit, we have built an array $arr_data that contains all form data. Add the new pair for the image to the array $arr_data as follows.

$arr_data = array(
    'title' => $_POST['title'],
    'summary' => $_POST['summary'],
    'video_path' => $_FILES['file']['tmp_name'],
    'image_path' => $_FILES['image']['tmp_name'], // here we are passing image
);

Next, after uploading the video on YouTube, we have to take the video id and assign a custom thumbnail to the video.

<?php
...
...
echo "Video uploaded successfully. Video ID is ". $response->id;
 
//upload thumbnail
$videoId = $response->id;
 
$chunkSizeBytes = 1 * 1024 * 1024;
 
$client->setDefer(true);
 
$setRequest = $service->thumbnails->set($videoId);
 
$media = new Google_Http_MediaFileUpload(
    $client,
    $setRequest,
    'image/png',
    null,
    true,
    $chunkSizeBytes
);
$imagePath = $arr_data['image_path'];
$media->setFileSize(filesize($imagePath));
 
$status = false;
$handle = fopen($imagePath, "rb");
 
while (!$status && !feof($handle)) {
    $chunk  = fread($handle, $chunkSizeBytes);
    $status = $media->nextChunk($chunk);
}
 
fclose($handle);
 
$client->setDefer(false);
echo "Thumbnail URL: ". $status['items'][0]['default']['url'];

Delete Video from YouTube Channel using YouTube API

You may also want a code to delete videos using YouTube API. In order to delete a video, you require an additional scope https://www.googleapis.com/auth/youtube which I have already included in a config file. It means the access token generated by following the above steps has the ability to delete a video.

Below is the code which will delete a video from your YouTube channel.

<?php
require_once 'config.php';
 
delete_video('VIDEO_ID_HERE');
 
function delete_video($id) {
     
    $client = new Google_Client();
      
    $db = new DB();
     
    $arr_token = (array) $db->get_access_token();
    $accessToken = array(
        'access_token' => $arr_token['access_token'],
        'expires_in' => $arr_token['expires_in'],
    );
     
    try {
        $client->setAccessToken($accessToken);
        $service = new Google_Service_YouTube($client);
        $service->videos->delete($id);
    echo 'Video deleted successfully.';
    } catch(Exception $e) {
        if( 401 == $e->getCode() ) {
            $refresh_token = $db->get_refersh_token();
 
            $client = new GuzzleHttp\Client(['base_uri' => 'https://accounts.google.com']);
 
            $response = $client->request('POST', '/o/oauth2/token', [
                'form_params' => [
                    "grant_type" => "refresh_token",
                    "refresh_token" => $refresh_token,
                    "client_id" => GOOGLE_CLIENT_ID,
                    "client_secret" => GOOGLE_CLIENT_SECRET,
                ],
            ]);
 
            $data = (array) json_decode($response->getBody());
            $data['refresh_token'] = $refresh_token;
 
            $db->update_access_token(json_encode($data));
 
            delete_video($id);
        } else {
            //echo $e->getMessage(); //print the error just in case your video is not uploaded.
        }
    }
}

That’s it! I hope you got to know how to upload a video on the YouTube channel using the YouTube API. I would like to hear your thoughts or suggestions in the comment section below.

Related Articles

If you liked this article, then please subscribe to our YouTube Channel for video tutorials.

43 thoughts on “How to use YouTube API to Upload Video on YouTube Channel

  1. After upload my video get’s Private (locked) and also got email regarding this video,
    Hi ,

    Our team has reviewed your content, and we think you may need to make changes to make sure it doesn’t violate our spam, deceptive practices and scams policy. In the meantime, we’ve made the following content private:

    Video: Nature video

    We haven’t applied a strike to your channel, and if you make changes, or if you think we’ve made a mistake, you can request to make your content public again. However, there may be some instances where YouTube keeps your content private.

  2. Salam, Thanks you a lot for this tutorial, I did it 100% works without any error, but the problem please i could like you to help with is that, the video is uploaded as private not as public even though the setPrivacyStatus is set to public, please help with that, and also can you show how to upload thumbnail images. Thanks you my man

  3. First of all thank you,
    But
    This line give There is a syntax error .any other way ? I am useing CS6
    $client = new GuzzleHttp\Client([‘base_uri’ => ‘https://accounts.google.com’]);

    $response = $client->request(‘POST’, ‘/o/oauth2/token’, [
    ‘form_params’ => [
    “grant_type” => “refresh_token”,
    “refresh_token” => $refresh_token,
    “client_id” => GOOGLE_CLIENT_ID,
    “client_secret” => GOOGLE_CLIENT_SECRET,
    ],
    ]);

  4. First of all thank you very much for the great tutorial. I have followed all the steps mentioned in the tutorial. However, i don’t get the video go to the channel. I get a successfuly insert message and also get the video id. Can you please help what i;m missing.
    Anxiously waiting your reply

  5. Thanks For this …..This helps a Lot…

    And also I need code snippet to delete uploaded video Using Youtube API….

  6. Thank man. This really helped me.
    Though I had some challenges enabling the youtube upload scope but in the end I was able to resolve it.

  7. If possible I have used Youtube API on my Application and any user visit my application and upload video to my channel…?

    1. Yes. Once you generate the access token, using the form created in the tutorial users can upload the video to your channel.

  8. Hi,

    i have a question regarding the uploading section to youtube,
    i have file that in internal directory like ../videos/abc.mp4
    so i don’t need to upload video to fullfilment form, i can call video file from directory
    how to modify the script uploading?

    thank you so much, for your answer

  9. Hi,

    I have the above code implemented on my VPS and I have also executed the composer command. When I load the index.php with a browser, it goes through authentication process but at the end it give me the following error message and the video is not uploaded to YouTube:
    “The session state did not match.”

    Please advise.

    Thanks,
    Sha Rok

  10. I have tried to get this to work, but it doesn’t work for me, sadly.
    I load the page, choose a Video, I get the “Authorization Required” Message, I click the link, follow the procedure, login, accept/allow what is asked for. After that i get redirected to the inital page and everything starts again.
    Is there anything I am missing? Does anybody have the same Problem?

  11. Is possible upload video without consume my api quota? If I upload 3 videos my 10k quota is almost over 🙁

  12. when i try to use this code in my project.i got the error like this

    require_once(): Failed opening required ‘vendor/autoload.php’ (include_path=’C:\xampp\php\PEAR’)
    can anyone help me to solve this problem please

    1. Did you install the library? In the article, you will find the command to install Google library composer require google/apiclient:~2.0

  13. when i try to use this code in my project.i got the error like this

    main(): Failed opening required ‘vendor/autoload.php’ (include_path=’C:\xampp\php\PEAR’)

    can anyone help me to solve this problem

  14. How to upload a video in a specific channel. I need to a app where anyone upload a video using this platform in a youtube channel (Channel name predefined in my code. User login not required ).

    1. We can upload video to only those channels which credentials(API keys) we have. We can’t upload video to others channel on YouTube.

      1. Yes I have channels credentials(API keys) but I want to upload videos from multiple user in same channel. I try your demo but videos uploaded in user channel.

        1. I understand. YouTube API generate access token based on logged in users credentials that why it’s uploading in user channel. I will research if there is any solution possible for it.

  15. Do we need to create Google API only once to open a Youtube Account or we would need to have and create a Google API for each video we upload?

Leave a Reply

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