Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload video to Youtube using Youtube API V3 and PHP

I am trying to upload a video to Youtube using PHP. I am using Youtube API v3 and I am using the latest checked out source code of Google API PHP Client library.
I am using the sample code given on
https://code.google.com/p/google-api-php-client/ to perform the authentication. The authentication goes through fine but when I try to upload a video I get Google_ServiceException with error code 500 and message as null.

I had a look at the following question asked earlier: Upload video to youtube using php client library v3 But the accepted answer doesn't describe how to specify file data to be uploaded.
I found another similar question Uploading file with Youtube API v3 and PHP, where in the comment it is mentioned that categoryId is mandatory, hence I tried setting the categoryId in the snippet but still it gives the same exception.

I also referred to the Python code on the the documentation site ( https://developers.google.com/youtube/v3/docs/videos/insert ), but I couldn't find the function next_chunk in the client library. But I tried to put a loop (mentioned in the code snippet) to retry on getting error code 500, but in all 10 iterations I get the same error.

Following is the code snippet I am trying:

$youTubeService = new Google_YoutubeService($client);
if ($client->getAccessToken()) {
    print "Successfully authenticated";
    $snippet = new Google_VideoSnippet();
    $snippet->setTitle = "My Demo title";
    $snippet->setDescription = "My Demo descrition";
    $snippet->setTags = array("tag1","tag2");
    $snippet->setCategoryId(23); // this was added later after refering to another question on stackoverflow

    $status = new Google_VideoStatus();
    $status->privacyStatus = "private";

    $video = new Google_Video();
    $video->setSnippet($snippet);
    $video->setStatus($status);

    $data = file_get_contents("video.mp4"); // This file is present in the same directory as the code
    $mediaUpload = new Google_MediaFileUpload("video/mp4",$data);
    $error = true;
    $i = 0;

    // I added this loop because on the sample python code on the documentation page
    // mentions we should retry if we get error codes 500,502,503,504
    $retryErrorCodes = array(500, 502, 503, 504);
    while($i < 10 && $error) {
        try{
            $ret = $youTubeService->videos->insert("status,snippet", 
                                                   $video, 
                                                   array("data" => $data));

            // tried the following as well, but even this returns error code 500,
            // $ret = $youTubeService->videos->insert("status,snippet", 
            //                                        $video, 
            //                                        array("mediaUpload" => $mediaUpload); 
            $error = false;
        } catch(Google_ServiceException $e) {
            print "Caught Google service Exception ".$e->getCode()
                  . " message is ".$e->getMessage();
            if(!in_array($e->getCode(), $retryErrorCodes)){
                break;
            }
            $i++;
        }
    }
    print "Return value is ".print_r($ret,true);

    // We're not done yet. Remember to update the cached access token.
    // Remember to replace $_SESSION with a real database or memcached.
    $_SESSION['token'] = $client->getAccessToken();
} else {
    $authUrl = $client->createAuthUrl();
    print "<a href='$authUrl'>Connect Me!</a>";
}

Is it something that I am doing wrong?

like image 685
jayendrap Avatar asked Jan 09 '13 13:01

jayendrap


People also ask

Can I upload video to YouTube with API?

The YouTube API upload video integration allows you or your users to easily upload and share a video, and even set a thumbnail, playlist, visibility to share a private, public or unlisted video, and the video description. The video can be directly uploaded to YouTube either with our API or Dashboard.

How much video can I upload on YouTube using API?

Uploads a video to YouTube and optionally sets the video's metadata. This method supports media upload. Uploaded files must conform to these constraints: Maximum file size: 256GB.


3 Answers

I was able to get the upload working using the following code:

if($client->getAccessToken()) {     $snippet = new Google_VideoSnippet();     $snippet->setTitle("Test title");     $snippet->setDescription("Test descrition");     $snippet->setTags(array("tag1","tag2"));     $snippet->setCategoryId("22");      $status = new Google_VideoStatus();     $status->privacyStatus = "private";      $video = new Google_Video();     $video->setSnippet($snippet);     $video->setStatus($status);      $error = true;     $i = 0;      try {         $obj = $youTubeService->videos->insert("status,snippet", $video,                                          array("data"=>file_get_contents("video.mp4"),                                          "mimeType" => "video/mp4"));     } catch(Google_ServiceException $e) {         print "Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage(). " <br>";         print "Stack trace is ".$e->getTraceAsString();     } } 
like image 88
jayendrap Avatar answered Sep 21 '22 13:09

jayendrap


I realize this is old, but here's the answer off the documentation:

    // REPLACE this value with the path to the file you are uploading.     $videoPath = "/path/to/file.mp4";      $snippet = new Google_Service_YouTube_VideoSnippet();     $snippet->setTitle("Test title");     $snippet->setDescription("Test description");     $snippet->setTags(array("tag1", "tag2"));      // Numeric video category. See     // https://developers.google.com/youtube/v3/docs/videoCategories/list      $snippet->setCategoryId("22");      // Set the video's status to "public". Valid statuses are "public",     // "private" and "unlisted".     $status = new Google_Service_YouTube_VideoStatus();     $status->privacyStatus = "public";      // 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); 
like image 45
Any Day Avatar answered Sep 19 '22 13:09

Any Day


I also realize this is old, but as I cloned the latest version of php-client from GitHub I ran in to trouble with Google_Service_YouTube_Videos_Resource::insert()-method.

I would pass an array with "data" => file_get_contents($pathToVideo) and "mimeType" => "video/mp4" set as an argument for the insert()-method, but I still kept getting (400) BadRequest in return.

Debugging and reading through Google's code i found in \Google\Service\Resource.php there was a check (on lines 179-180) against an array key "uploadType" that would initiate the Google_Http_MediaFielUpload object.

$part = 'status,snippet';
$optParams = array(
    "data" => file_get_contents($filename),
    "uploadType" => "media",  // This was needed in my case
    "mimeType" => "video/mp4",
);
$response = $youtube->videos->insert($part, $video, $optParams);

If I remember correctly, with version 0.6 of the PHP-api the uploadType argument wasn't needed. This might apply only for the direct upload style and not the resumable upload shown in Any Day's answer.

like image 29
Gemmu Avatar answered Sep 19 '22 13:09

Gemmu