Tôi đang cố gắng tạo ứng dụng máy chủ để tải video lên YouTube. Trong ứng dụng máy chủ của tôi, người dùng có thể tải video trực tiếp lên kênh YouTube của tôi để công khai.Tải lên Youtube API PHP, ngoại lệ: Không thể bắt đầu tải lên lại, tải lên phải được gửi đến URL tải lên
- Phần client của ứng dụng của tôi mua lại video và tải lên nó vào máy chủ của tôi.
- Máy chủ của tôi sau đó sử dụng API YouTube để tải video lên kênh YouTube của tôi.
Để làm công việc này, tôi đã tạo ra một ứng dụng web giả có thể nắm bắt những dấu hiệu làm mới được tạo ra và tôi đã lưu trữ nó trong một tập tin key.txt
{"access_token":"MYTOKEN","token_type":"Bearer","expires_in":3600,"created":1435654774}
Kịch bản upload_video.php
sẽ tự động cập nhật "key.txt"
tập tin nếu access_token
đã lỗi thời. Đây là mã từ 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();
}
Khi kịch bản chạy, nó nâng cao ngoại lệ này:
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}
ngoại lệ huy động vào getResumeUri()
(dòng 281) trong Google_Http_MediaFileUpload
, tôi đã var đổ phản hồi từ 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] =>
)
Điều gì là sai? Cảm ơn bạn đã giúp đỡ và xin lỗi vì tiếng Anh xấu.
hoàn hảo, cảm ơn! – ar099968
cố định trong các cam kết mới nhất trên github –