Failed to start the resumable upload (HTTP 404) - php

Here is my code, I am trying for a couple of hours to fix this problem, the only error that I am getting is: Failed to start the resumable upload (HTTP 404)
Is there a way to see more error details, or do you guys know what may cause this error? I have granted access and everything, I check for expired tokens as well, but can't upload a video b/c of this.
Please at least a hint about how can I see more error details.
......
//Check if token is valid
if($this->client->isAccessTokenExpired()){
//var_dump($this->client->getAccessToken());
$NewAccessToken = json_decode($this->client->getAccessToken());
$d = $this->client->refreshToken($NewAccessToken->refresh_token);
$this->client->setAccessToken(trim($this->client->getAccessToken()));
}
.........
try{
// REPLACE this value with the path to the file you are uploading.
$videoPath = $_FILES['video']['tmp_name'];
// 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($_POST['title']);
$snippet->setDescription($this->input->post('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 = "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.
$this->client->setDefer(true);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$ext= finfo_file($finfo, $_FILES['video']['tmp_name']);
// Create a request for the API's videos.insert method to create and upload the video.
$insertRequest = $this->youtube->videos->insert("status,snippet", $video,
array("data"=>file_get_contents($_FILES['video']['tmp_name']),
"uploadType" => "media",
"mimeType" => 'application/octet-stream'));
// Create a MediaFileUpload object for resumable uploads.
$media = new Google_Http_MediaFileUpload(
$this->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
$this->client->setDefer(false);
$videoID = $status['id'];
} catch (Google_ServiceException $e) {
$response['success'] = 'Failed to upload video, contact support! a Message:'.$e->getMessage();
return $this->output
->set_content_type('application/json')
->set_output(json_encode($response));
} catch (Google_Exception $e) {
$response['success'] = 'Failed to upload video, contact support! b Message:'.$e->getMessage();
return $this->output
->set_content_type('application/json')
->set_output(json_encode($response));
}
//LE
! ) Fatal error: Uncaught exception 'Google_Exception' with message 'Failed to start the resumable upload (HTTP 404)' in /home/user/app/vendor/google/apiclient/src/Google/Http/MediaFileUpload.php on line 299
( ! ) Google_Exception: Failed to start the resumable upload (HTTP 404) in /home/user/app/vendor/google/apiclient/src/Google/Http/MediaFileUpload.php on line 299
Call Stack
# Time Memory Function Location
1 0.0004 285400 {main}( ) .../index.php:0
2 0.0162 1112448 require_once( '/home/user/app/system/core/CodeIgniter.php' ) .../index.php:210
3 0.0633 4532576 call_user_func_array:{/home/mio/zsuite-dev/system/core/CodeIgniter.php:359} ( ) .../CodeIgniter.php:359
4 0.0634 4534256 Presentation->index( ) .../CodeIgniter.php:359
5 0.4291 8672016 Presentation->_save_update_presentation( ) .../presentation.php:155
6 0.4952 9206376 Google_Http_MediaFileUpload->nextChunk( ) .../presentation.php:289
7 0.4952 9206736 Google_Http_MediaFileUpload->getResumeUri( ) .../MediaFileUpload.php:138

You should check your php error logs.
In Linux environment it should be at: var/log/httpd/error_log
In Windows environment you should check your php.ini
error_log = c:/server/php.log line to find the location.
EDIT: if you don't have errors enabled, change the following line in your php.ini
log_errors = On
and reproduce the error.
EDIT2: the following page also seems to have a lot of samples if you haven't already looked at it.

ClientLogin for Google has been shutdown: see here
I recently had to re-code authentication on an app to fix the issue. You must now use OAuth to authenticate with Google. The good news: there is plenty of code out there to help you including on Google: OAuth2

Related

Upload video to specific playlist

I am uploading video to my channel with youtube data api. This works perfectly but when i upload video it uploads in my channel. I want it to upload in given playlist.(I have some already created playlists). Is there any way i can give playlistId in following code. I dont want to use playlistitem.insert.
thanks in Advance
$OAUTH2_CLIENT_ID = 'ds';
$OAUTH2_CLIENT_SECRET = 'sd';
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
$tokenExisted = $this->Token->find('first');
if(!empty($tokenExisted)){
$token = $tokenExisted['Token']['token'];
$refreshToken = $tokenExisted['Token']['ref_token'];
$client->refreshToken($refreshToken);
$token = $client->getAccessToken();
}
if (isset($token)) {
$client->setAccessToken($token);
}
if ($client->isAccessTokenExpired()){
$refreshToken = $tokenExisted['Token']['ref_token'];
$client->refreshToken($refreshToken);
$token = $client->getAccessToken();
}else{
$token = $client->getAccessToken();
}
$token=json_encode($token);
// Check to ensure that the access token was successfully acquired.
if ($token) {
try{
// REPLACE this value with the path to the file you are uploading.
$videoPath = $dest . '/' . $img_name . '.' . $image['1'];
// 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($input['title']);
$snippet->setDescription($input['description']);
//$snippet->playlistId($playlistId);
// Numeric video category. See
// https://developers.google.com/youtube/v3/docs/videoCategories/list
$snippet->setCategoryId($input['category']);
// 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(false);
// 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);
} catch (Google_Service_Exception $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()));
}
} 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();
}
According to this SO answer, you cannot upload video directly into a playlist. It's normal that when uploading video, it will redirect to your channel. Once it's uploaded in the channel, you can now put it in the playlist.
If the video is already uploaded, you can follow this Adding a video to a playlist documentation. You can add a video to a playlist by using a VideoEntry object.
Here's a sample code retrieves a VideoEntry object with a known entry ID and then adds it to the playlist corresponding to the PlaylistListEntry object. Since the request does not specify a position where the video will appear in the playlist, the new video is added to the end of the playlist.
$postUrl = $playlistToAddTo->getPlaylistVideoFeedUrl();
// video entry to be added
$videoEntryToAdd = $yt->getVideoEntry('4XpnKHJAok8');
// create a new Zend_Gdata_PlaylistListEntry, passing in the underling DOMElement of the VideoEntry
$newPlaylistListEntry = $yt->newPlaylistListEntry($videoEntryToAdd->getDOM());
// post
try {
$yt->insertEntry($newPlaylistListEntry, $postUrl);
} catch (Zend_App_Exception $e) {
echo $e->getMessage();
}
Here's a related SO post which might help:
Youtube API (PHP) - how to add (existing) video to existing playlist?

How can i upload video on specific channel using YouTube API in PHP?

I want to make functionality for users to upload video on my channel without authentication (if needed). IS it possible ?
Please help me .
Thanks
OM
Yes Omprakash,it is possible
You will need Google APIs Client Library for PHP.
You will also need to create a project on
https://console.developers.google.com/ and get credentials(i.e
client secret & client id).
Finally,you will need to generate access token for specific channel.
Please take a look at this link
(https://youtube-eng.googleblog.com/2013/06/google-page-identities-and-youtube-api_24.html)
to generate access token.
Once you have all these things ready with you,you can use ready made
example code available in Google APIs Client Library for PHP to upload
video on YouTube.
Note: This is not in detail process.It is not possible to explain all of the process in detail on stack-overflow. But, once you get close to solution,you can re-post or put comment for further assistance.
This is example code to upload video on YouTube. Hope, it will help you
/*include google libraries */
require_once '../api/src/Google/autoload.php';
require_once '../api/src/Google/Client.php';
require_once '../api/src/Google/Service/YouTube.php';
$application_name = 'Your application/project name created on google developer console';
$client_secret = 'Your client secret';
$client_id = 'Your client id';
$scope = array('https://www.googleapis.com/auth/youtube.upload', 'https://www.googleapis.com/auth/youtube', 'https://www.googleapis.com/auth/youtubepartner');
try{
$key = file_get_contents('the_key.txt'); //it stores access token obtained in step 3
$videoPath = 'video path on your server goes here';
$videoTitle = 'video title';
$videoDescription = 'video description';
$videoCategory = "22"; //please take a look at youtube video categories for videoCategory.Not so important for our example
$videoTags = array('tag1', 'tag2','tag3');
// Client init
$client = new Google_Client();
$client->setApplicationName($application_name);
$client->setClientId($client_id);
$client->setAccessType('offline');
$client->setAccessToken($key);
$client->setScopes($scope);
$client->setClientSecret($client_secret);
if ($client->getAccessToken()) {
/**
* Check to see if our access token has expired. If so, get a new one and save it to file for future use.
*/
if($client->isAccessTokenExpired()) {
$newToken = json_decode($client->getAccessToken());
$client->refreshToken($newToken->refresh_token);
file_put_contents('the_key.txt', $client->getAccessToken());
}
$youtube = new Google_Service_YouTube($client);
// Create a snipet with title, description, tags and category id
$snippet = new Google_Service_YouTube_VideoSnippet();
$snippet->setTitle($videoTitle);
$snippet->setDescription($videoDescription);
$snippet->setCategoryId($videoCategory);
$snippet->setTags($videoTags);
// Create a video status with privacy status. Options are "public", "private" and "unlisted".
$status = new Google_Service_YouTube_VideoStatus();
$status->setPrivacyStatus('public');
// Create a YouTube video with snippet and status
$video = new Google_Service_YouTube_Video();
$video->setSnippet($snippet);
$video->setStatus($status);
// Size of each chunk of data in bytes. Setting it higher leads faster upload (less chunks,
// for reliable connections). Setting it lower leads better recovery (fine-grained chunks)
$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);
/**
* Video has successfully been upload, now lets perform some cleanup functions for this video
*/
if ($status->status['uploadStatus'] == 'uploaded') {
$youtube_id = $status->id; //you got here youtube video id
} else {
// handle failere here
}
// If you want to make other calls after the file upload, set setDefer back to false
$client->setDefer(true);
} else{
// #TODO Log error
echo 'Problems creating the client';
}
} catch(Google_Service_Exception $e) {
echo "\r\n Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage();
echo "\r\n Stack trace is ".$e->getTraceAsString();
} catch (Exception $e) {
echo "\r\n Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage();
echo "\r\n Stack trace is ".$e->getTraceAsString();
}

How to upload Video to YouTube using Google API PHP Client Library and Youtube API V3?

Trying to simply upload video using Google API PHP Client (latest release 1.1.6), but code in Youtube API V3 is not working and giving 500 internal server error.
What is wrong with code below when I am not using any bleeding edge beta version, I have just masked 3 parameters below otherwise it is copied form Youtube API V3.
require_once 'google-api-php-client/src/Google/Client.php';
require_once 'google-api-php-client/src/Google/Service/YouTube.php';
session_start();
$OAUTH2_CLIENT_ID = 'CHANGE1-0osfh0p5h80o9ol2uqtsjq5i7r1jun.apps.googleusercontent.com';
$OAUTH2_CLIENT_SECRET = 'CHANGE2azMpt__VdSt9';
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
$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']);
}
// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
try{
// REPLACE this value with the path to the file you are uploading.
$videoPath = "/CHANGE3/videos/test.mp4";
// 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("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);
$htmlBody .= "<h3>Video Uploaded</h3><ul>";
$htmlBody .= sprintf('<li>%s (%s)</li>',
$status['snippet']['title'],
$status['id']);
$htmlBody .= '</ul>';
} catch (Google_Service_Exception $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();
} 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
<h3>Authorization Required</h3>
<p>You need to authorize access before proceeding.<p>
END;
}
echo $htmlBody;
A service error occurred: Error calling PUT https://www.googleapis.com/upload/youtube/v3/videos?part=status%2Csnippet&uploadType=resumable&upload_id=AEnB2UpXd4UQ0dt-v2_8YLzDp4KAywZQUIgUEm3Lxyv7nV_ZLAHghu6RiNE0e82xMMGx9ztQvTdYGFwvSNP5yJiOdffS0CuG-Q: (400) Failed to parse Content-Range header.
Don't mark it duplicate of very old and deprecated questions below, as you can see other questions even included files in their code that are not present in latest Google API PHP Client library or are referring to dead Google Code Project. Similar outdated question 1, 2, 3, 4, 5
Strangely a very small tweak in code fixes the problem.
Instead of just $videoPath = "/path/to/file.mp4"; using DOCUMENT_ROOT solves the issue. Other than that code of documentation is perfect.
$videoPath = $_SERVER["DOCUMENT_ROOT"] . "/mapapp/videos/test.mp4";
for other whoe comes around and deal with "Failed to parse Content-Range header"
I was searching for 3 days and finaly i found my solution...
my file was bigger then 4gb and xampp on windows (my webserver tool) is just 32bit so the fopen() command could not read my big files.
I installaed apache 64bit and php7 64bit by my own and it is gone
At this moment my script finaly loads chunks on big files
794 - 07:14:15 - 832569344
795 - 07:14:16 - 833617920
796 - 07:14:17 - 834666496
797 - 07:14:18 - 835715072
798 - 07:14:19 - 836763648
799 - 07:14:19 - 837812224
800 - 07:14:20 - 838860800
801 - 07:14:21 - 839909376
802 - 07:14:22 - 840957952
803 - 07:14:23 - 842006528
804 - 07:14:24 - 843055104
allready 804 chunks ^^ no truncate nothign :D just uploading flawless

YouTube PHP API v3 - Upload Fails when including recordingDetails - Invalid value for Double

I'm trying to add recordingDetails to an upload call. It seems to work fine on small test files, but with larger files I'm getting the following error:
Failed to start the resumable upload (HTTP 400: global, Invalid value for Double: )
With the help of some debugging code I was able to find out this error happens when executing this line of code: $status = $media->nextChunk($chunk);
If i comment out $video->setRecordingDetails($recordingDetails); the same file uploads fine.
I'm new to the API, and I can't seem to find anything related to this error online. Any guidance or suggestions would be greatly appreciated!
My code is below:
# Get file info for upload
$resource=get_resource_data($ref);
$alternative=-1;
$ext=$resource["file_extension"];
$videoPath=get_resource_path($ref,true,"",false,$ext,-1,1,false,"",$alternative);
// 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($video_title);
$snippet->setDescription($video_description);
$snippet->setTags(array($video_keywords));
$snippet->setCategoryId($video_category);
// Set the video's status to "public". Valid statuses are "public",
// "private" and "unlisted".
$status = new Google_Service_YouTube_VideoStatus();
$status->privacyStatus = $video_status;
$status->setLicense($video_publish_license);
$status->setPublicStatsViewable($video_public_stats_viewable);
//
$recordingDetails=new Google_Service_YouTube_VideoRecordingDetails();
$locationdetails=new Google_Service_YouTube_GeoPoint();
$locationdetails->setLatitude($resource['geo_lat']);
$locationdetails->setLongitude($resource['geo_long']);
$recordingDetails->setLocation($locationdetails);
// Associate the snippet and status objects with a new video resource.
$video = new Google_Service_YouTube_Video();
$video->setSnippet($snippet);
$video->setStatus($status);
$video->setRecordingDetails($recordingDetails);
// 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.
if(!is_numeric($youtube_chunk_size)){$youtube_chunk_size=10;}
$chunkSizeBytes = intval($youtube_chunk_size) * 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,recordingDetails", $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(true);
$youtube_new_url = "https://www.youtube.com/watch?v=" . $status['id'];
return array(true,$youtube_new_url);
}
catch (Google_ServiceException $e)
{
$errortext= sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
catch (Google_Exception $e)
{
$errortext= sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
catch (Google_ServiceException $e)
{
$errortext = sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
catch (Google_Exception $e)
{
$errortext = sprintf('<p>A client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
if(isset($errortext))
{
return array(false,$errortext);
}
It seems you set an "invalid" value on an object and from your details I understand is related to Google_Service_YouTube_VideoRecordingDetails or Google_Service_YouTube_GeoPoint. My guess is that you are setting coordinates in wrong format but is just a guess. Try comment this line $recordingDetails->setLocation($locationdetails); and check the result. I've experienced same kind of problem with google drive (if I uncomment line with createdTime i get Fatal error: Uncaught exception 'Google_Exception' with message 'Failed to start the resumable upload (HTTP 400: global, Invalid value for: Invalid format: "1463431798" is malformed at "8")' in /home/ubuntu/workspace/gdrive/vendor/google/apiclient/src/Google/Http/MediaFileUpload.php:334)
$file = new Google_Service_Drive_DriveFile();
$file->title = "repkit.tar.gz";
// $file->createdTime = time();
So maybe Double is referring to some expected format and the only place I can guess are coordinates.
Hope this give you some clue.

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?
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();
}
}
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);
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.
The answer would be using Google_Http_MediaFileUpload through the Google PHP client libraries.
Here's the sample code: https://github.com/youtube/api-samples/blob/master/php/resumable_upload.php

Categories