YouTube Browser-Based Uploader with PHP

Aug 21 2012

Download Example

RD2 wanted to add something special with our 3rd iteration of building the World Traveler Internship website. We created a very unique feature within the application process. The users could upload their submission video and with a little behind the scenes magic, the video is automatically added to a designated World Traveler Internship YouTube account and added to their bio page on the website.

This is made possible using YouTube’s browser-based uploading API v2.0. The example that the API gives you are good, but not great. I wasn’t able to find examples for exactly what I needed in PHP. So I created my own 2 step process for uploading the user’s file to YouTube.

Before you start, I would suggest downloading the example and looking at that as you read the below code. Below are the steps you will need in order to create your browser-based YouTube uploader:

1. Create your 2 step form

index.php

<!-- Step 1 of the youtube upload process -->
<?php if( empty( $_POST['video_title'] ) && $unique_id == "" ) : ?>
    <form action="" method="post">
        <label for="video_title">Video Title</label>
        <input type="text" name="video_title" />
        <label for="video_description">Video Description</label>
        <textarea id="video-description" name="video_description"></textarea>
        <input type="submit" value="Step 2" />
    </form> <!-- /form -->

<!-- Step 2 -->
<?php elseif( $response->token != '' ) : ?>
    <h4>Title:</h4>
    <p><?php echo $video_title; ?></p>
    <h4>Description:</h4>
    <p><?php echo $video_description; ?></p>
    <form action="<?php echo( $response->url ); ?>?nexturl=<?php echo( urlencode( $nexturl ) ); ?>" method="post" enctype="multipart/form-data">
        <p class="block">
            <label>Upload Video</label>
            <span class="youtube-input">
                <input id="file" type="file" name="file" />
            </span>
        </p>
        <input type="hidden" name="token" value="<?php echo( $response->token ); ?>"/>
        <input type="submit" value="Upload Video" />
    </form> <!-- /form -->

2. Get the Youtube Token

Once the form is submitted, you will need to submit the title and description to YouTube. YouTube will return a token that you will then use to upload your video.

index.php

<?php
//If the 1st step form has been submited, run the token script.
if( isset( $_POST['video_title'] ) && isset( $_POST['video_description'] ) ) {
    $video_title = stripslashes( $_POST['video_title'] );
    $video_description = stripslashes( $_POST['video_description'] );
    include_once( 'get_youtube_token.php' );
}
?>

get_youtube_token.php code:

<?php
$youtube_email = ""; // Change this to your youtube sign in email.
$youtube_password = ""; // Change this to your youtube sign in password.
// Developer key: Get your key here: http://code.google.com/apis/youtube/dashboard/.
$key = "";

$source = ''; // A short string that identifies your application for logging purposes.
$postdata = "Email=".$youtube_email."&Passwd=".$youtube_password."&service=youtube&source=" . $source;
$curl = curl_init( "https://www.google.com/youtube/accounts/ClientLogin" );
curl_setopt( $curl, CURLOPT_HEADER, "Content-Type:application/x-www-form-urlencoded" );
curl_setopt( $curl, CURLOPT_POST, 1 );
curl_setopt( $curl, CURLOPT_POSTFIELDS, $postdata );
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, 0 );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 1 );
$response = curl_exec( $curl );
curl_close( $curl );

list( $auth, $youtubeuser ) = explode( "\n", $response );
list( $authlabel, $authvalue ) = array_map( "trim", explode( "=", $auth ) );
list( $youtubeuserlabel, $youtubeuservalue ) = array_map( "trim", explode( "=", $youtubeuser ) );

$youtube_video_title = $video_title; // This is the uploading video title.
$youtube_video_description = $video_description; // This is the uploading video description.
$youtube_video_keywords = "demo"; // This is the uploading video keywords.
$youtube_video_category = "Tech"; // This is the uploading video category. There are only certain categories that are accepted. See below
/*
 * Accepted Categories:
 *
    Film
    Autos
    Music
    Animals
    Sports
    Travel
    Shortmov
    Games
    Videblog
    People
    Comedy
    Entertainment
    News
    Howto
    Education
    Tech
    Nonprofit
    Movies
    Movies_anime_action
    Movies_action_adventure
    Movies_classics
    Movies_comedy
    Movies_documentary
    Moves_drama
    Movies_family
    Movies_foreign
    Movies_horror
    Movies_sci_fi_fantasy
    Movies_thriller
    Movies_shorts
    Shows
    Trailers
 */

$data = '<?xml version="1.0"?>
            <entry xmlns="http://www.w3.org/2005/Atom"
              xmlns:media="http://search.yahoo.com/mrss/"
              xmlns:yt="http://gdata.youtube.com/schemas/2007">
              <media:group>
                <media:title type="plain">' . stripslashes( $youtube_video_title ) . '</media:title>
                <media:description type="plain">' . stripslashes( $youtube_video_description ) . '</media:description>
                <media:category
                  scheme="http://gdata.youtube.com/schemas/2007/categories.cat">'.$youtube_video_category.'</media:category>
                <media:keywords>'.$youtube_video_keywords.'</media:keywords>
              </media:group>
            </entry>';

$headers = array( "Authorization: GoogleLogin auth=".$authvalue,
             "GData-Version: 2",
             "X-GData-Key: key=".$key,
             "Content-length: ".strlen( $data ),
             "Content-Type: application/atom+xml; charset=UTF-8" );

$curl = curl_init( "http://gdata.youtube.com/action/GetUploadToken");
curl_setopt( $curl, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"] );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_TIMEOUT, 10 );
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $curl, CURLOPT_POST, 1 );
curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt( $curl, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $curl, CURLOPT_POSTFIELDS, $data );
curl_setopt( $curl, CURLOPT_REFERER, true );
curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt( $curl, CURLOPT_HEADER, 0 );

$response = simplexml_load_string( curl_exec( $curl ) );
curl_close( $curl );
?>

At this point, we check to make sure we have our YouTube token ( $response ), and then show step 2 of our form.

3. Submit the video using the YouTube token and url.

Once the user submits the video to YouTube, it will return 2 url get variables, the status of the video and the id. If the status is 200, then the video upload was successful.

index.php

<?php
// Specifies the url that youtube will return to. The data it returns are as get variables
$nexturl = "http://example.com/uploader";
// These are the get variables youtube returns once the video has been uploaded.
$unique_id = $_GET['id'];
$status = $_GET['status'];
?>

You can then display a message once the YouTube video is uploaded successfully.

index.php

<!-- Final Step -->
<?php elseif( $unique_id != '' && $status = '200' ) : ?>
<div id="video-success">
    <h4>Video Successfully Uploaded!</h4>
    <p>Video's usually take around 2-3 hours to get accepted by youtube. Please check back soon.</p>
    <p>Here is your url to view your video:<a href="http://www.youtube.com/watch?v=<?php echo $unique_id; ?>" target="_blank">http://www.youtube.com/watch?v=<?php echo $unique_id; ?></a></p>
</div> <!-- /div#video-success -->
<?php endif; ?>

That should be it! Please download the example and leave a comment below if this article was useful to you.

Download Example

29 Comments to “YouTube Browser-Based Uploader with PHP”

  1. Colin – Thank you for posting this, it was exactly what I was looking for. I agree that the PHP sample was good but not great. Thanks again!

    By Mike Fritzsche on August 26th, 2012 at 8:30 pm
  2. What do you have to fill in $source?

    By Sharp on August 28th, 2012 at 10:57 am
  3. Sharp, the description the API gives for the $source is ‘a short string that identifies your application for logging purposes’. I have updated the content to reflect this in the code. Thanks for catching this! For more information, visit: this page.

    By Colin Mitchell on August 28th, 2012 at 11:08 am
  4. K, thx. Just one question how do you upload the video private?

    By Sharp on August 28th, 2012 at 12:20 pm
  5. Not sure how to do this without messing around with the code. But I found documentation in the API for uploading private videos.

    By Colin Mitchell on August 28th, 2012 at 1:56 pm
  6. I have downloaded the Example RD2. I have entered my youtube login information and Developer Key. I have uploaded it to my server. When I enter the video title and the video description and click the step 2 button to submit it I get the following error message

    Fatal error: Call to undefined function: simplexml_load_string() in /homepages/30/d154816103/htdocs/uploader/get_youtube_token.php on line 96
    I am not a programer so any help you can give me would be greatly appreciated. If you could email me directly that would be appreciated as well.

    By Steve on October 13th, 2012 at 12:32 am
  7. Steve, I’m not sure why you are getting this error. I just downloaded and tested the exact code and did not get any errors. You may have issues with your values you entered for the developer key, etc. Your website may be running PHP 4 which does not support simplexml_load_string(). PHP 5 does, so you may want to check that.

    By Colin Mitchell on October 15th, 2012 at 9:50 am
  8. Your script works like a charm. when I try to integrate it with ajax, Youtube API throws 302 error. Do you have any suggestion for this.

    By Sathish on October 21st, 2012 at 1:51 am
  9. Sathish, I’m glad the script works for you. I have not tried to do this with an AJAX request. With the complexity of what the YouTube API is doing, I wouldn’t think AJAX would work since the request is cross-domain and having to pass a unique token each time. I’m sorry I couldn’t be of more help, but I would challenge yourself to keep it as a normal HTTP request, but adding visual cues for the user to make it seem like AJAX.

    By Colin Mitchell on October 22nd, 2012 at 9:56 am
  10. When I am trying to run this. I am getting this error. please help. what needs to be done?

    Fatal error: Call to undefined function curl_init() in C:\wamp\www\get_youtube_token.php on line 9

    By Jignesh on November 16th, 2012 at 4:46 pm
  11. Jignesh, that’s a very unusual error. curl_init() is a PHP function that has been around since PHP 4+. See php.net’s documentation for more information. http://php.net/manual/en/function.curl-init.php

    I would make sure you included all the files correctly, and also test it on a staging environment and not your local to see if that works. Not sure what else would be wrong.

    By Colin Mitchell on November 16th, 2012 at 5:05 pm
  12. Hey Thanks. It is working now. May I know how can we retrieve the video which we have uploaded to our channel on Youtube.

    By Jignesh on November 18th, 2012 at 2:57 pm
  13. Jignesh, that’s great you got it working! Once the video is submitted to YouTube, it will return 2 url get variables, the status of the video and the id. If the status is 200, then the video upload was successful. The other is the ID of the YouTube video. For example, in my ‘Final Step’ part of my code, I output a message and a link to the video.

    This will output your YouTube ID: < ?php echo $_GET['id']; ?>

    By Colin Mitchell on November 19th, 2012 at 9:33 am
  14. Hello Colin, can you help me with this issue?
    I am getting this error: yt:authenticationUnknown for the upload authorization process. All user, pass, key are correct

    By Ion on November 22nd, 2012 at 1:19 pm
  15. Ion, that is definitely a YouTube authentication error. It might be due to the developer key not being registered correctly with your domain your testing on. I would setup a new key for your testing environment to see if that works, or testing on a staging server.

    By Colin Mitchell on November 26th, 2012 at 9:25 am
  16. Hello Colin.
    How can I delete the video using the same logic? I am trying to delete the video providing header as given https://developers.google.com/youtube/2.0/developers_guide_protocol_updating_and_deleting_videos#Deleting_a_video …but I am not getting anything in response.

    By Mark on December 3rd, 2012 at 11:53 am
  17. Mark, I have not tried deleting a video yet. Without diving in and testing it myself, I’m not sure of a good solution to your problem. I will take this into consideration about an update to this post in the future.

    Sorry I can’t be of more help.

    By Colin Mitchell on December 3rd, 2012 at 12:55 pm
  18. Hi i uploaded ur code on my server but when i m submitting first fro then i m getting blank page plz help me out……

    By sam on December 19th, 2012 at 5:56 am
  19. I also get a blank page.

    Browser-based Youtube Uploader Script

    label,
    input {
    display: block;
    margin: 0 0 5px 0;
    }

    By Simeon on February 3rd, 2013 at 9:50 am
  20. Found the fix

    Change line 32 in index.php….

    from this

    to this

    By Simeon on February 3rd, 2013 at 10:11 am
  21. Hey Colin,

    I’ve been having a lot of fun with this. It works great when I use the form version of your scipt, but if I try to upload a video with PHP directly from my server to YouTube I get a “Moved Temporarily” response from YouTube. Do you have any ideas how to solve this issue? I’m new to CURL programming so maybe you can give me a tip. Basically I’m just trying to push the final form to YouTube using CURL but get the “Moved Temporarily” message. I’m wondering if there are extra CURL parameters to set up in the same way you did in the “get_youtube_token.php” file?

    Here’s my code:

    $video_title = “Test3″;
    $video_description = “Brian desription”;

    include_once( ‘get_youtube_token.php’ );

    $response_token = ($response->token);
    $response_url = $response->url;
    $form_url = $response_url . “?nexturl=http://example.com/users/”;

    $ch = curl_init( $form_url );

    $postdata = array(“token=”.$response_token.”&file[]” => “@/”.realpath(‘/var/www/youtube-uploader/1.avi’).”;type=video/x-msvideo”);

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(“Content-type: multipart/form-data”));
    curl_setopt( $ch, CURLOPT_POST, 1 );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, $postdata );
    curl_exec( $ch );
    curl_close( $ch );

    By Brian Ruff on February 5th, 2013 at 5:00 pm
  22. thank for your script.

    By saurabh nagar on February 11th, 2013 at 3:52 am
  23. Can you tell me, please direct uploading to Youtube :(

    By Fatih on February 12th, 2013 at 2:21 pm
  24. Thanks a lot for your script! Was really looking for a way to get our site’s users to upload videos directly to our youtube channel. this helped a lot :)

    By Akhilesh Anandh on February 19th, 2013 at 5:28 am
  25. Akhilesha -

    Awesome to hear! Glad you like it.

    By Colin Mitchell on February 19th, 2013 at 9:26 am
  26. I have uploaded the pages and scripts etc but after I click on to step two the page goes blank. I have entered my account password and key properly, but still no avail.

    I see someone had the same problem but resolved it by changing something in line 32?? I cant see what that is, so I am not sure how to fix it. I really need this feature! Please help!

    By Evan on February 21st, 2013 at 11:24 am
  27. To all who are having issues with the blank screen -

    I have just downloaded the example and it worked for me. I am currently in the process of trying to figure out why there are many of you having issues. I will be uploading updated code soon that may or may not fix this problem.

    There may be a few reasons why you are seeing the blank screen
    1. You are not getting a response token from YouTube
    2. Your Account Permissions are not set correct

    Hopefully with the updated code (coming before February 25), we can solve this issue.

    Thanks everyone for their patience. RD2 is keeping me pretty busy these days.

    By Colin Mitchell on February 21st, 2013 at 1:41 pm
  28. Great. Thanks for the response. I have been looking around for a fix, took a break and I have decided to come back to try again. Maybe you are right and it is something with my account permissions, or something with the 0Auth 2.0 token.

    I will have a look, If I can’t fix it I will return for a possible work around/fix

    Thanks for all your hard work!

    By Evan on February 21st, 2013 at 2:10 pm
  29. Thank You so much it works fine

    By vivek on March 6th, 2013 at 3:00 am