Google API's php client library - YouTube chunked upload ERROR - php

I'm using Google API's PHP client library and when I use this solution:
https://stackoverflow.com/a/14552052/1181479
and the same as here
https://developers.google.com/youtube/v3/code_samples/php#resumable_uploads
witch contain such logic:
if ($client->getAccessToken()) {
$videoPath = "path/to/foo.mp4";
$snippet = new Google_VideoSnippet();
$snippet->setTitle("Test title2");
$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);
$chunkSizeBytes = 1 * 1024 * 1024;
$media = new Google_MediaFileUpload('video/mp4', null, true, $chunkSizeBytes);
$media->setFileSize(filesize($videoPath));
$result = $youtube->videos->insert("status,snippet", $video,
array('mediaUpload' => $media));
$status = false;
$handle = fopen($videoPath, "rb");
while (!$status && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$uploadStatus = $media->nextChunk($result, $chunk);
}
fclose($handle);
}
The main problem is this error:
ErrorException [ Recoverable Error ]: Argument 1 passed to Google_MediaFileUpload::nextChunk() must be an instance of Google_HttpRequest, instance of Google_Video given, called in /opt/code/host/resulinkpro/www/application/classes/Controller/Upload.php on line 132 and defined
the core of that stuff is:
$media is Google_Video class
and
$media->nextChunk($result, $chunk);
requires $result to be Google_HttpRequest SO Google documentation and any example in web will not help to achieve that task at all! Last chance on you guys!
Thank you!

Both of the examples were made for PHP client 0.6.3, I believe you are trying it with 1.0 version. You can read about migrating here.
We hope to post the updated examples really soon.

Related

Google API client (YouTube) errors

I'm trying to implement uploading video to YouTube from the server but I'm having problems with that. I'm using Laravel 9 and Google API client for php. The code is like this, pretty much the same as a google example:
public function goToAuthUrl() {
$client = new Client();
$client->setApplicationName('Test');
$client->setScopes([
YouTube::YOUTUBE_UPLOAD,
]);
$client->setAuthConfig('client_secret_***.apps.googleusercontent.com.json');
$client->setAccessType('offline');
$authUrl = $client->createAuthUrl();
return redirect()->away($authUrl);
}
public function youtubeHandle(Request $request) {
session_start();
$htmlBody = '';
$client = new Google_Client();
$client->setAuthConfigFile('client_secret_***.apps.googleusercontent.com.json');
$client->setRedirectUri('https://***/youtube');
$client->addScope(YouTube::YOUTUBE_UPLOAD);
if (!isset($request->code)) {
$auth_url = $client->createAuthUrl();
} else {
$accessToken = $client->fetchAccessTokenWithAuthCode($request->code);
$client->setAccessToken($accessToken);
try{
$videoPath = url('storage/images/rain.mp4');
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
$snippet = new Google_Service_YouTube_VideoSnippet();
$snippet->setTitle("Test title");
$snippet->setDescription("Test description");
$snippet->setTags(array("test"));
// Numeric video category.
$snippet->setCategoryId(27);
// 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.
$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(Storage::size('public/images/rain.mp4'));
// 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();
}
echo $htmlBody;
So, oauth process goes well, first I run goToAuthUrl() function, give the permissions, it redirects me back to the website and runs youtubeHandle() function. And here are the problems. It throws an error
Invalid request. The number of bytes uploaded is required to be equal or greater than 262144, except for the final request (it's recommended to be the exact multiple of 262144). The received request contained 16098 bytes, which does not meet this requirement.
and points to this line $status = $media->nextChunk($chunk);.
I tried to find the solutions and change the code, like changing $insertRequest variable to this:
$insertRequest = $youtube->videos->insert("status,snippet", $video, [
'data' => file_get_contents(url('storage/images/rain.mp4')),
'mimeType' => 'video/*',
'uploadType' => 'multipart'
]);
This way it throws another error
Failed to start the resumable upload (HTTP 200)
and video isn't being created on the channel.
Could you tell me where's the problem?
Once again I make sure that to make a question is a half way to get an answer. I found a solution, the example I used is old but it's there in the documentation. If someone meet this problem - it's all about chunks and there's a function to get it:
private function readVideoChunk($handle, $chunkSize) {
$byteCount = 0;
$giantChunk = "";
while (!feof($handle)) {
// fread will never return more than 8192 bytes if the stream is read
// buffered and it does not represent a plain file
$chunk = fread($handle, 8192);
$byteCount += strlen($chunk);
$giantChunk .= $chunk;
if ($byteCount >= $chunkSize) {
return $giantChunk;
}
}
return $giantChunk;
}
So uploading should look like this:
// Read the media file and upload it chunk by chunk.
$status = false;
$handle = fopen($videoPath, "rb");
while (!$status && !feof($handle)) {
$chunk = $this->readVideoChunk($handle, $chunkSizeBytes);
$status = $media->nextChunk($chunk);
}

Google Drive API GuzzleHttp\Exception\RequestException

Following the instructions for these topics:
https://github.com/google/google-api-php-client/issues/788
https://developers.google.com/api-client-library/php/guide/media_upload
I tried to fix the problem below and upload files to Google Drive:
Fatal error: Uncaught GuzzleHttp\Exception\RequestException: cURL error 60: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in /secret/public_html/v5/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:187 Stack trace: #0 /secret/public_html/v5/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(150): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array) #1 /secret/public_html/v5/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(103): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory)) #2 /secret/public_html/v5/vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php(43): GuzzleHttp\Handler\CurlFactory::fin in /secret/public_html/v5/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php on line 187
Using the APIs in PHP, when the file is less than 5 MB, it does not show the error, however, files larger than this generate the above error. Is the problem the API or the certificate? Even installing it on my linux server the error continues, does anyone know how to fix this problem? Or have you ever faced something like that?
Here is the code I'm using to upload up to 5 MB that is working.
<?php
$client = new Google_Client();
$client->setAuthConfig("client_secret.json");
$client->setIncludeGrantedScopes(true);
$client->setAccessType("offline");
$client->setAccessToken($access_token);
$drive_service = new Google_Service_Drive($client);
$mime_type = mime_content_type($uploadfile);
$file = new Google_Service_Drive_DriveFile();
$result = $drive_service->files->create($file, array(
"data" => file_get_contents($uploadfile),
"mimeType" => $mime_type,
"uploadType" => "media"
));
Following is the code I'm using to upload a larger 5 MB that is not working.
<?php
$client = new Google_Client();
$client->setAuthConfig("client_secret.json");
$client->setIncludeGrantedScopes(true);
$client->setAccessType("offline");
$client->setAccessToken($access_token);
$drive_service = new Google_Service_Drive($client);
$mime_type = mime_content_type($uploadfile);
$file = new Google_Service_Drive_DriveFile();
$file->title = $uploadname;
$chunkSizeBytes = 1 * 1024 * 1024;
$client->setDefer(true);
$request = $drive_service->files->create($file); // insert
$media = new Google_Http_MediaFileUpload($client, $request, $mime_type, null, true, $chunkSizeBytes);
$media->setFileSize(filesize($uploadfile));
$status = false;
$handle = fopen($uploadfile, "rb");
while (!$status && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$status = $media->nextChunk($chunk);
}
$result = false;
if($status != false) {
$result = $status;
}
fclose($handle);
$client->setDefer(false);

Insert object to Google Cloud Storage at specific route using PHP

I am amazed by the lack of information at the official documentation of Google Cloud Storage with PHP.
Here we go... I'm trying to manage bucket's uploads and downloads with Google APIs Client Library for PHP, but I can't find anywhere the way to specify to the API where I want to upload my files at google's bucket (I can only upload them at bucket's root).
Here's the code that I'm using for the upload (extracted from https://github.com/guillefd/Backup-manager-gcs/blob/master/application/libraries/Googlecloudstorage.php):
public function media_file_upload($file_path = null, $file_name = null) {
# init
$result = new stdClass();
$result->error = null;
$result->status = null;
$result->exception = null;
# timer
$result->starttime = microtime();
# init gcs api
$gso = new Google_Service_Storage_StorageObject();
$gso->setName($file_name);
$gso->setBucket($this->bucket);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo,$file_path);
$chunkSizeBytes = 1 * 1024 * 1024;
$this->client->setDefer(true);
$filetoupload = array(
'name'=>$file_name,
'uploadType'=>'resumable'
);
# service
$this->newStorageService();
$status = false;
# try
try {
$request = $this->storageService->objects->insert($this->bucket, $gso, $filetoupload);
$media = new Google_Http_MediaFileUpload($this->client, $request, $mimetype, null, true, $chunkSizeBytes);
$media->setFileSize(filesize($file_path));
$handle = fopen($file_path, "rb");
# loop chunks
while(!$status && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$status = $media->nextChunk($chunk);
}
fclose($handle);
$this->client->setDefer(false);
// $result->status = $status;
} catch(Exception $e) {
$result->error = true;
$result->status = 'Google Cloud Service upload failed';
$result->exception = $e;
}
# timer
$result->endtime = microtime();
$result->totaltime = $this->get_totaltime($result);
# verify response
$result->httpcode = http_response_code();
$result->error = isset($status->kind) && $status->kind==self::STORAGE_OBJECT ? false : true;
return $result;
}
The main question that I'm actually asking is: Is there a way to upload files to google's bucket at a specific route, using Google Cloud's PHP API?
Thanks!

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

Getting a video from S3 and Uploading to YouTube in PHP

I have some code working that uploads a video file up to YouTube:
$yt = new Zend_Gdata_YouTube($httpClient);
// create a new VideoEntry object
$myVideoEntry = new Zend_Gdata_YouTube_VideoEntry();
// create a new Zend_Gdata_App_MediaFileSource object
$filesource = $yt->newMediaFileSource('file.mov');
$filesource->setContentType('video/quicktime');
// set slug header
$filesource->setSlug('file.mov');
I have videos in S3 and I want to upload them to YouTube. The video in our S3 account is public, so i can use a command like wget. Should I run a command that wgets the video file and downloads it locally before I run this script (shell_exec("wget ".$s3videoURL))?
Or should I try to enter the MediaFileSource as the URL of the S3 file itself?
Mainly, I just need stability (not a solution subject to frequent time-outs); speed and local storage isn't really important (I can locally delete video file once its been uploaded).
What would be the best way to go about this?
Thanks!
Update: I should probably mention that this script is going to be uploading about 5 videos to YouTube per execution.
This is an old question but i believe i have a better answer.
You don't have to write video to HDD and you can't keep the whole thing in RAM (I assume it is a big file).
You can use PHP AWS SDK and Google Client libraries to buffer file from S3 and send it to YouTube on the fly. Use registerStreamWrapper method to register S3 as file system and use resumable uploads from YouTube API. Then all you have to do is reading chunks from S3 with fread and sending them to YouTube. This way you can even limit the RAM usage.
I assume you created the video object ($video in code) from Google_Video class. This is a complete code.
<?php
require_once 'path/to/libraries/aws/vendor/autoload.php';
require_once 'path/to/libraries/google-client-lib/autoload.php';
use Aws\S3\S3Client;
$chunkSizeBytes = 2 * 1024 * 1024; // 2 mb
$streamName = 's3://bucketname/video.mp4';
$s3client = S3Client::factory(array(
'key' => S3_ACCESS_KEY,
'secret' => S3_SECRET_KEY,
'region' => 'eu-west-1' // if you need to set.
));
$s3client->registerStreamWrapper();
$client = new Google_Client();
$client->setClientId(YOUTUBE_CLIENT_ID);
$client->setClientSecret(YOUTUBE_CLIENT_SECRET);
$client->setAccessToken(YOUTUBE_TOKEN);
$youtube = new Google_YoutubeService($client);
$media = new Google_MediaFileUpload('video/*', null, true, $chunkSizeBytes);
$filesize = filesize($streamName); // use it as a reguler file.
$media->setFileSize($filesize);
$insertResponse = $youtube->videos->insert("status,snippet", $video, array('mediaUpload' => $media));
$uploadStatus = false;
$handle = fopen($streamName, "r");
$totalReceived = 0;
$chunkBuffer = '';
while (!$uploadStatus && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$chunkBuffer .= $chunk;
$chunkBufferSize = strlen($chunkBuffer);
if($chunkBufferSize > $chunkSizeBytes) {
$fullChunk = substr($chunkBuffer, 0, $chunkSizeBytes);
$leapChunk = substr($chunkBuffer, $chunkSizeBytes);
$uploadStatus = $media->nextChunk($insertResponse, $fullChunk);
$totalSend += strlen($fullChunk);
$chunkBuffer = $leapChunk;
echo PHP_EOL.'Status: '.($totalReceived).' / '.$filesize.' (%'.(($totalReceived / $filesize) * 100).')'.PHP_EOL;
}
$totalReceived += strlen($chunk);
}
$extraChunkLen = strlen($chunkBuffer);
$uploadStatus = $media->nextChunk($insertResponse, $chunkBuffer);
$totalSend += strlen($chunkBuffer);
fclose($handle);
The "MediaFileSource" must be a real file. It won't take a URL, so you will need to copy the videos to your server from S3, before sending them to YouTube.
You can probably get away with the "shell_exec" if your usage is light, but for a variety of reasons its probably better to use either the Zend S3 Service, or cURL to pull files from S3.
I had to make some changes to #previous_developer 's answer to make it work with Youtube Data API V3 (Please upvote him as I could not find any working code except his).
$streamName = 's3://BUCKET-NAME/VIDEO.mp4';
/**
Since I have been using Yii 2. Use the AWS
SDK directly instead.
*/
$aws = Yii::$app->awssdk->getAwsSdk();
$s3client = $aws->createS3();
$s3client->registerStreamWrapper();
$service = new \Google_Service_YouTube($client);
$snippet = new \Google_Service_YouTube_VideoSnippet();
$snippet->setTitle("Test title");
$snippet->setDescription("Test descrition");
$snippet->setTags(array("tag1","tag2"));
$snippet->setCategoryId("22");
$status = new \Google_Service_YouTube_VideoStatus();
$status->privacyStatus = "public";
$video = new \Google_Service_YouTube_Video();
$video->setSnippet($snippet);
$video->setStatus($status);
$client->setDefer(true);
$insertResponse = $service->videos->insert("status,snippet", $video);
$media = new MediaFileUpload(
$client,
$insertResponse,
'video/*',
null,
true,
false
);
$filesize = filesize($streamName); // use it as a reguler file.
$media->setFileSize($filesize);
$chunkSizeBytes = 2 * 1024 * 1024; // 2 mb
$uploadStatus = false;
$handle = fopen($streamName, "r");
$totalSend = 0;
$totalReceived = 0;
$chunkBuffer = '';
while (!$uploadStatus && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$chunkBuffer .= $chunk;
$chunkBufferSize = strlen($chunkBuffer);
if($chunkBufferSize > $chunkSizeBytes) {
$fullChunk = substr($chunkBuffer, 0, $chunkSizeBytes);
$leapChunk = substr($chunkBuffer, $chunkSizeBytes);
$uploadStatus = $media->nextChunk($fullChunk);
$totalSend += strlen($fullChunk);
$chunkBuffer = $leapChunk;
echo PHP_EOL.'Status: '.($totalReceived).' / '.$filesize.' (%'.(($totalReceived / $filesize) * 100).')'.PHP_EOL;
}
$totalReceived += strlen($chunk);
}
$extraChunkLen = strlen($chunkBuffer);
$uploadStatus = $media->nextChunk($chunkBuffer);
$totalSend += strlen($chunkBuffer);
fclose($handle);
// If you want to make other calls after the file upload, set setDefer back to false
$client->setDefer(false);
$chunkSizeBytes = 2 * 1024 * 1024; // 2 mb
$s3client = $this->c_aws->getS3Client();
$s3client->registerStreamWrapper();
try {
$client = new \Google_Client();
$client->setAccessType("offline");
$client->setApprovalPrompt('force');
$client->setClientId(GOOGLE_CLIENT_ID);
$client->setClientSecret(GOOGLE_CLIENT_SECRET);
$token = $client->fetchAccessTokenWithRefreshToken(GOOGLE_REFRESH_TOKEN);
$client->setAccessToken($token);
$youtube = new \Google_Service_YouTube($client);
// 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($title);
$snippet->setDescription($summary);
$snippet->setTags(explode(',', $keywords));
// 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);
// 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);
$insertRequest = $youtube->videos->insert("status,snippet", $video);
$media = new \Google_Http_MediaFileUpload(
$client,
$insertRequest,
'video/*',
null,
true,
$chunkSizeBytes
);
$result = $this->c_aws->getAwsFile($aws_file_path);
$media->setFileSize($result['ContentLength']);
$uploadStatus = false;
// Seek to the beginning of the stream
$result['Body']->rewind();
// Read the body off of the underlying stream in chunks
while (!$uploadStatus && $data = $result['Body']->read($chunkSizeBytes)) {
$uploadStatus = $media->nextChunk($data);
}
$client->setDefer(false);
if ($uploadStatus->status['uploadStatus'] == 'uploaded') {
// Actions to perform for a successful upload
$uploaded_video_id = $uploadStatus['id'];
return ($uploadStatus['id']);
}
}catch (\Google_Service_Exception $exception){
return '';
print_r($exception);
}

Categories