如何使用 Google API PHP 客户端库和 Youtube API V3 将视频上传到 YouTube?
How to upload Video to YouTube using Google API PHP Client Library and Youtube API V3?
尝试使用 Google API PHP Client (latest release 1.1.6), but code in Youtube API V3 简单地上传视频无效,并出现 500 内部服务器错误。
当我没有使用任何前沿测试版时,下面的代码有什么问题,我刚刚屏蔽了下面的 3 个参数,否则它是从 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 <a href="$authUrl">authorize access</a> before proceeding.<p>
END;
}
echo $htmlBody;
发生服务错误: 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.
不要将其标记为以下非常陈旧和已弃用的问题的重复项,因为您可以看到其他问题甚至在其代码中包含最新 Google API PHP Client library or are referring to dead Google Code Project. Similar outdated question 1, 2, 3, 4, 5[=30 中不存在的文件=]
奇怪的是,代码中的一个非常小的调整就解决了这个问题。
而不是 $videoPath = "/path/to/file.mp4";
使用 DOCUMENT_ROOT 解决了这个问题。除了文档代码是完美的。
$videoPath = $_SERVER["DOCUMENT_ROOT"] . "/mapapp/videos/test.mp4";
对于其他过来处理的人"Failed to parse Content-Range header"
我搜索了 3 天,终于找到了解决方案...
我的文件大于 4gb,windows(我的网络服务器工具)上的 xampp 只有 32 位,所以 fopen() 命令无法读取我的大文件。
我自己安装了 apache 64 位和 php7 64 位,但它不见了
此时我的脚本终于加载大文件块
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
全部准备好 804 个块 ^^ 没有截断任何内容 :D 只是上传完美
尝试使用 Google API PHP Client (latest release 1.1.6), but code in Youtube API V3 简单地上传视频无效,并出现 500 内部服务器错误。
当我没有使用任何前沿测试版时,下面的代码有什么问题,我刚刚屏蔽了下面的 3 个参数,否则它是从 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 <a href="$authUrl">authorize access</a> before proceeding.<p>
END;
}
echo $htmlBody;
发生服务错误: 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.
不要将其标记为以下非常陈旧和已弃用的问题的重复项,因为您可以看到其他问题甚至在其代码中包含最新 Google API PHP Client library or are referring to dead Google Code Project. Similar outdated question 1, 2, 3, 4, 5[=30 中不存在的文件=]
奇怪的是,代码中的一个非常小的调整就解决了这个问题。
而不是 $videoPath = "/path/to/file.mp4";
使用 DOCUMENT_ROOT 解决了这个问题。除了文档代码是完美的。
$videoPath = $_SERVER["DOCUMENT_ROOT"] . "/mapapp/videos/test.mp4";
对于其他过来处理的人"Failed to parse Content-Range header"
我搜索了 3 天,终于找到了解决方案...
我的文件大于 4gb,windows(我的网络服务器工具)上的 xampp 只有 32 位,所以 fopen() 命令无法读取我的大文件。
我自己安装了 apache 64 位和 php7 64 位,但它不见了
此时我的脚本终于加载大文件块
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
全部准备好 804 个块 ^^ 没有截断任何内容 :D 只是上传完美