How to upload AWS S3 file to YouTube API - php

Here is a difficult one... I have managed to adapt the AWS API easily but Google's Oauth2 is not working in my code... I have tried adapting code from StackOverflow and other sources... I have tried the YouTube upload code generator to only fail the upload. I have tried other code available (older Youtube Data API (Google ^2.0)... My biggest problem is that some code examples don't include the API Version which errors in Classes being unidentified... Other code plainly doesn't work... This is my weeks holy grail... Please advise.
<?php
require_once '../aws/aws-autoloader.php';
require_once 'vendor/autoload.php';
use Aws\S3\S3Client;
$chunkSizeBytes = 2 * 1024 * 1024; // 2 mb
$streamName = 's3://gb-football-tribunal-live/1616710690-605d0c226862f-1-0.mp4';
$s3client = S3Client::factory(array(
'version' => 'latest',
'key' => 'MyS3Key',
'secret' => 'MyS3Secret',
'region' => 'eu-west-1' // if you need to set.
));
$s3client->registerStreamWrapper();
$client = new Google_Client();
$client->setApplicationName('cGbYt');
$client->setAuthConfig('client_secret.json');
$client->setAccessType('offline');
$client->setScopes([
'https://www.googleapis.com/auth/youtube.upload',
]);
// Define service object for making API requests.
$service = new Google_Service_YouTube($client);
// Define the $video object, which will be uploaded as the request body.
$video = new Google_Service_YouTube_Video();
// Add 'snippet' object to the $video object.
$videoSnippet = new Google_Service_YouTube_VideoSnippet();
$videoSnippet->setCategoryId('17');
$videoSnippet->setChannelId('UCC7fqHtOns6DtnR7QcaJMaw');
$videoSnippet->setDescription('Testing of Test00001');
$videoSnippet->setTags(['Football', 'Test']);
$videoSnippet->setTitle('Test 00001');
$video->setSnippet($videoSnippet);
// Add 'status' object to the $video object.
$videoStatus = new Google_Service_YouTube_VideoStatus();
$videoStatus->setEmbeddable(true);
$videoStatus->setLicense('youtube');
$videoStatus->setPrivacyStatus('public');
$videoStatus->setUploadStatus('uploaded');
$video->setStatus($videoStatus);
$queryParams = [
'autoLevels' => false,
'notifySubscribers' => true,
'onBehalfOfContentOwner' => 'MyYoutTubeUserID',
'onBehalfOfContentOwnerChannel' => 'MyYouTubeChannelID',
'stabilize' => false,
'uploadType' => 'resumable',
'alt' => 'json',
'fields' => 'items(snippet(id))',
];
$response = $service->videos->insert(
'snippet,status',
$video,
$queryParams,
array(
'data' => file_get_contents($s3client),
'mimeType' => 'application/octet-stream',
'uploadType' => 'multipart'
)
);
print_r($response);
?>

Related

how to get statuscode from aws s3 putobject response

I am sending file to AWS s3 using PHP SDK. I installed SDK using
composer require aws/aws-sdk-php
I am using following code
require_once('vendor/autoload.php');
$s3 = new Aws\S3\S3Client([
'region' => AWS_REGION,
'version' => 'latest',
'credentials' => [
'key' => AWS_ACCESS_KEY_ID,
'secret' => AWS_SECRET_ACCESS_KEY,
]
]);
$result = $s3->putObject([
'Bucket' => AWS_BUCKET,
'Key' => $filename,
'SourceFile' => $fileFullPath
]);
Following response, I am getting
I am trying to get status code from this response and tried different ways, but I could not get status code.
You are returned an object with a private array called "data" but you are also able to just call the data by attribute. So using $result['#metadata']['statusCode'] works just fine.
$result['#metadata']['statusCode'] == 200
According to your example.
Worked fine for me
$result['#metadata']['statusCode'] == 200

Google API file create permissions

Hi I am creating a new google drive file via the PHP SDK like so :
$driveService = new Google_Service_Drive($client);
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => $filename,
'parents' => array('root')));
$content = file_get_contents($filepath.'.csv');
$file = $driveService->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => 'text/csv',
'uploadType' => 'media'));
And setting it's permissions.
$user_email = $driveService->about->get(array('fields' => 'user'))->getUser()->getemailAddress();
$userPermission = new Google_Service_Drive_Permission(array(
'type' => 'user',
'role' => 'writer',
'emailAddress' => $user_email
));
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => $filename,
'parents' => array('root')));
$content = file_get_contents($filepath.'.csv');
When I try and access the file in the google drive gui, I can see the files but when I try to open/ download them I get a authorisation error:
Access to doc-0g-0c-docs.googleusercontent.com was denied
On download Or
Authorisation requeired
If I try to open in the google notepad. I also cannot open them in google docs.
Client set up code :
$client = new Google_Client();
if (!empty(get_option('access_token')) && !$reset) {
$credentials_file = plugin_dir_path(__FILE__) .
get_option('credentials_filename');
$client->setAuthConfig($credentials_file);
$client->setPrompt('select_account consent');
$client->setApplicationName("Client_Library_Examples");
$client->addScope(Google_Service_Drive::DRIVE);
$client->setRedirectUri( plugin_dir_url( __FILE__ ) . '/oauth2callback.php');
$client->setAccessType('offline'); // offline access
$client->setIncludeGrantedScopes(true);
$client->setAccessToken(get_option('access_token'));

AWS S3 authorization mechanism - Signature 4

I'm currently struggling with getting a S3 download link working. I've been using this code as reference but when I try to open the file, I get the error:
The authorization mechanism you have provided is not supported. Please
use AWS4-HMAC-SHA256.
I tried a few other scripts floating around, but all ended with some other error message.
Is there an easy way to migrate the script I'm using to make it work with Signature v4?
UPDATE: as suggested by hjpotter92, I used the AWS-SDK and came up with this working code:
$client = S3Client::factory([
'version' => 'latest',
'region' => 'eu-central-1',
'signature' => 'v4',
'credentials' => [
'key' => '12345',
'secret' => 'ABCDE'
]
]);
$cmd = $client->getCommand('GetObject', [
'Bucket' => '###name###',
'Key' => $fileName
]);
$request = $client->createPresignedRequest($cmd, '+2 minutes');
$presignedUrl = (string) $request->getUri();
return $presignedUrl;

Laravel AWS PHP SDK - CreatePlatformEndpoint throws 400 Bad Request

I am using "aws/aws-sdk-php-laravel": "~3.0"
When i am trying to register the android device its throwing the error.
Below is the snapshot of it.
I tried with 2 different code formats but both gives the same exception.
$device = 'gcm_id_here';
$sns = App::make('aws')->createClient('sns');
$result = $sns->createPlatformEndpoint(['Token' => 'device_unique_id',
'PlatformApplicationArn' => $device]);
// or
$credentials = new Credentials('key', 'secret');
$client = new SnsClient([
'version' => 'latest',
'region' => 'us-west-2',
'credentials' => $credentials
]);
$SNSEndPointData = $client->createPlatformEndpoint([
'PlatformApplicationArn' => $device,
'Token' => 'device_unique_id'
]);
Please help me solve this issue.

Using s3 server-side encryption with PHP

I have decide to avail of amazons new server-side encryption with s3, however, I have run into a problem which I am unable to resolve.
I am using the s3 PHP class found here : https://github.com/tpyo/amazon-s3-php-class
I had been using this code to put objects originally (and it was working) :
S3::putObjectFile($file, $s3_bucket_name, $file_path, S3::ACL_PRIVATE,
array(),
array(
"Content-Disposition" => "attachment; filename=$filename",
"Content-Type" => "application/octet-stream"
)
);
I then did as instructed here : http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?RESTObjectPUT.html and added the 'x-amz-server-side​-encryption' request header. But now when I try to put an object it fails without error.
My new code is :
S3::putObjectFile($file, $s3_bucket_name, $file_path, S3::ACL_PRIVATE,
array(),
array(
"Content-Disposition" => "attachment; filename=$filename",
"Content-Type" => "application/octet-stream",
"x-amz-server-side​-encryption" => "AES256"
)
);
Has anybody experimented with this new feature or can anyone see an error in the code.
Cheers.
That header should be part of the $metaHeaders array and not $requestHeaders array.
S3::putObjectFile($file, $s3_bucket_name, $file_path, S3::ACL_PRIVATE,
array(
"x-amz-server-side​-encryption" => "AES256"
),
array(
"Content-Disposition" => "attachment; filename=$filename",
"Content-Type" => "application/octet-stream"
)
);
Here's the method definition from the docs:
putObject (mixed $input,
string $bucket,
string $uri,
[constant $acl = S3::ACL_PRIVATE],
[array $metaHeaders = array()],
[array $requestHeaders = array()])
You might also consider using the SDK for PHP?
We can upload files with encryption using the code following
$s3->create_object($bucket_name,$destination,array(
'acl'=>AmazonS3::ACL_PUBLIC,
'fileUpload' => $file_local,
'encryption'=>"AES256"));
And you can download latest sdk from here
With the official SDK:
use Aws\S3\S3Client;
$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';
// $filepath should be absolute path to a file on disk
$filepath = '*** Your File Path ***';
// Instantiate the client.
$s3 = S3Client::factory();
// Upload a file with server-side encryption.
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $filepath,
'ServerSideEncryption' => 'AES256',
));
Changing Server-Side Encryption of an Existing Object (Copy Operation)
use Aws\S3\S3Client;
$sourceBucket = '*** Your Source Bucket Name ***';
$sourceKeyname = '*** Your Source Object Key ***';
$targetBucket = '*** Your Target Bucket Name ***';
$targetKeyname = '*** Your Target Object Key ***';
// Instantiate the client.
$s3 = S3Client::factory();
// Copy an object and add server-side encryption.
$result = $s3->copyObject(array(
'Bucket' => $targetBucket,
'Key' => $targetKeyname,
'CopySource' => "{$sourceBucket}/{$sourceKeyname}",
'ServerSideEncryption' => 'AES256',
));
Source: http://docs.aws.amazon.com/AmazonS3/latest/dev/SSEUsingPHPSDK.html
With laravel 5+ it can be done easily through filesystems.php config, you don't need to get driver or low level object.
's3' => [
'driver' => 's3',
'key' => "Your Key",
'secret' => "Your Secret",
'region' => "Bucket Region",
'bucket' => "Bucket Name",
'options' => [
'ServerSideEncryption' => 'AES256',
]
],
//Code
$disk->put("filename", "content", "public"); // will have AES for file

Categories