Sto provando a creare un'applicazione server per il caricamento di video su YouTube. Nella mia applicazione server, l'utente può caricare un video direttamente sul mio canale YouTube per renderlo pubblico.API PHP Uploads di YouTube, eccezione: impossibile avviare il caricamento ripristinabile, il caricamento deve essere inviato all'URL di caricamento
- La parte client della mia applicazione acquisisce il video e lo carica al mio server.
- Il mio server utilizza quindi l'API di YouTube per caricare il video sul mio canale YouTube.
per fare questo lavoro, ho creato una Web Application fittizio in grado di catturare il token di aggiornamento generato e ho memorizzato in un file key.txt
{"access_token":"MYTOKEN","token_type":"Bearer","expires_in":3600,"created":1435654774}
Lo script upload_video.php
aggiornerà automaticamente "key.txt"
file se access_token
è scaduto. Questo è il codice da upload_video.php
:
$key = file_get_contents('key.txt');
$application_name = 'YouTube_Upload';
$client_secret = 'MY_CLIENT_SECRET';
$client_id = 'MY_CLIENT_ID';
$scope = array('https://www.googleapis.com/auth/youtube.upload', 'https://www.googleapis.com/auth/youtube', 'https://www.googleapis.com/auth/youtubepartner');
$videoPath = "Test.f4v";
$videoTitle = "A tutorial video";
$videoDescription = "A video tutorial on how to upload to YouTube";
$videoCategory = "22";
$videoTags = array("youtube", "tutorial");
try{
// 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 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('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('unlisted');
// 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
*/
if ($status->status['uploadStatus'] == 'uploaded') {
// Actions to perform for a successful upload
// ......
}
// If 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) {
print "Google_Service_Exception ".$e->getCode(). " message is ".$e->getMessage();
print "Stack trace is ".$e->getTraceAsString();
}catch (Exception $e) {
print "Exception ".$e->getCode(). " message is ".$e->getMessage();
print "Stack trace is ".$e->getTraceAsString();
}
Quando lo script viene eseguito, sollevare questa eccezione:
Exception 0 message is Failed to start the resume-able upload (HTTP 400: global, Uploads must be sent to the upload URL. Re-send this request to https://www.googleapis.com/upload/youtube/v3/videos?part=status,snippet&uploadType=resumable)Stack trace is
#0 D:\xampp\htdocs\youtube\src\Google\Http\MediaFileUpload.php(136): Google_Http_MediaFileUpload->getResumeUri()
#1 D:\xampp\htdocs\youtube\resumable_upload.php(100): Google_Http_MediaFileUpload->nextChunk('\x00\x00\x00\x1Cftypf4v \x00\x00\x00...')
#2 {main}
eccezione raise getResumeUri()
(linea 281) in Google_Http_MediaFileUpload
, ho var scaricare la risposta da parte di Google
Google_Http_Request Object
(
[batchHeaders:Google_Http_Request:private] => Array
(
[Content-Type] => application/http
[Content-Transfer-Encoding] => binary
[MIME-Version] => 1.0
)
[queryParams:protected] => Array
(
[part] => status,snippet
[uploadType] => resumable
)
[requestMethod:protected] => POST
[requestHeaders:protected] => Array
(
[content-type] => application/json; charset=UTF-8
[authorization] => Bearer XXXXXXXXXXXXXXXX
[content-length] => 187
[x-upload-content-type] => video/*
[x-upload-content-length] => 10201286
[expect] =>
)
[baseComponent:protected] => https://www.googleapis.com//upload
[path:protected] => /youtube/v3/videos
[postBody:protected] => {"snippet":{"categoryId":"22","description":"A video tutorial on how to upload to YouTube","tags":["youtube","tutorial"],"title":"A tutorial video"},"status":{"privacyStatus":"unlisted"}}
[userAgent:protected] =>
[canGzip:protected] =>
[responseHttpCode:protected] => 400
[responseHeaders:protected] => Array
(
[x-guploader-uploadid] => XXXXXXXXXXXXXXXXXXXXXXXXXX
[location] => https://www.googleapis.com/upload/youtube/v3/videos?part=status,snippet&uploadType=resumable
[vary] => Origin
X-Origin
[content-type] => application/json; charset=UTF-8
[content-length] => 468
[date] => Fri, 10 Jul 2015 09:54:30 GMT
[server] => UploadServer
[alternate-protocol] => 443:quic,p=1
)
[responseBody:protected] => {
"error": {
"errors": [
{
"domain": "global",
"reason": "wrongUrlForUpload",
"message": "Uploads must be sent to the upload URL. Re-send this request to https://www.googleapis.com/upload/youtube/v3/videos?part=status,snippet&uploadType=resumable"
}
],
"code": 400,
"message": "Uploads must be sent to the upload URL. Re-send this request to https://www.googleapis.com/upload/youtube/v3/videos?part=status,snippet&uploadType=resumable"
}
}
[expectedClass:protected] => Google_Service_YouTube_Video
[expectedRaw:protected] =>
[accessKey] =>
)
Cosa c'è che non va? Grazie per l'aiuto e scusa per il pessimo inglese.
perfetto, grazie! – ar099968
corretti negli ultimi commit su github –