使用Youtube API v3可恢复上传(在AWS EC2上)上传较大视频时出错


Error when uploading larger videos using Youtube API v3 resumable upload (on AWS EC2)

在我的AWS EC2实例上,我可以使用Youtube API(PHP)上传视频。我的视频文件存储在AWS S3上,所以当上传到Youtube时,我的PHP脚本会将文件下载到EC2,然后使用Youtube API上传到Youtube。

这似乎适用于小于100MB的视频,但不适用于大于100MB的文件。

有人知道可能是什么问题吗?以下是用于执行上传的库代码片段:

$snippet = new 'Google_Service_YouTube_VideoSnippet();
if (array_key_exists('title', $data))
{
    $snippet->setTitle($data['title']);
}
if (array_key_exists('description', $data))
{
    $snippet->setDescription($data['description']);
}
if (array_key_exists('tags', $data))
{
    $snippet->setTags($data['tags']);
}
if (array_key_exists('category_id', $data))
{
    $snippet->setCategoryId($data['category_id']);
}

/* ------------------------------------
#. Set the Privacy Status
------------------------------------ */
$status = new 'Google_Service_YouTube_VideoStatus();
$status->privacyStatus = $privacyStatus;
/* ------------------------------------
#. Set the Snippet & Status
------------------------------------ */
$video = new 'Google_Service_YouTube_Video();
$video->setSnippet($snippet);
$video->setStatus($status);
/* ------------------------------------
#. Set the Chunk Size
------------------------------------ */
$chunkSize = 1 * 1024 * 1024;
/* ------------------------------------
#. Set the defer to true
------------------------------------ */
$this->client->setDefer(true);
/* ------------------------------------
#. Build the request
------------------------------------ */
$insert = $this->youtube->videos->insert('status,snippet', $video);
/* ------------------------------------
#. Upload
------------------------------------ */
$media = new 'Google_Http_MediaFileUpload(
    $this->client,
    $insert,
    'video/*',
    null,
    true,
    $chunkSize
);
/* ------------------------------------
#. Set the Filesize
------------------------------------ */
$media->setFileSize(filesize($path));
/* ------------------------------------
#. Read the file and upload in chunks
------------------------------------ */
$status = false;
$handle = fopen($path, "rb");
while (!$status && !feof($handle)) {
    $chunk = fread($handle, $chunkSize);
    $status = $media->nextChunk($chunk);
}
fclose($handle);
/* ------------------------------------
#. Set the defer to false again
------------------------------------ */
$this->client->setDefer(true);

我打开CURLOPT_VERBOSE以查看上传过程中的输出,下面是它的摘录:

* Connection #0 to host www.googleapis.com left intact
* Hostname www.googleapis.com was found in DNS cache
*   Trying 74.125.130.95...
* Connected to www.googleapis.com (74.125.130.95) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
* Server certificate: *.googleapis.com
* Server certificate: Google Internet Authority G2
* Server certificate: GeoTrust Global CA
> PUT /upload/youtube/v3/videos?part=status%2Csnippet&uploadType=resumable&upload_id=AEnB2Ur4P0Fpf3GsMWAoc6dUIeXmQXuAfdhuIP1jIbQJPyVQm0aqZ0NGuljcT-U0c5hW2wrE-AepZMghHOzpvkUZb-I9zBruAw HTTP/1.1
Host: www.googleapis.com
Accept: */*
content-range: bytes 19922944-20971519/388638417
content-type: application/json; charset=UTF-8
content-length: 1048576
* We are completely uploaded and fine
< HTTP/1.1 308 Resume Incomplete
< X-GUploader-UploadID: AEnB2Ur4P0Fpf3GsMWAoc6dUIeXmQXuAfdhuIP1jIbQJPyVQm0aqZ0NGuljcT-U0c5hW2wrE-AepZMghHOzpvkUZb-I9zBruAw
< Range: bytes=0-20971519
< X-Range-MD5: 5f5ce9766e0b823edb947b9a93ee3fd6
< Content-Length: 0
< Date: Thu, 07 Apr 2016 09:01:06 GMT
< Server: UploadServer
< Content-Type: text/html; charset=UTF-8
< Alternate-Protocol: 443:quic
< Alt-Svc: quic=":443"; ma=2592000; v="32,31,30,29,28,27,26,25"
< 
* Connection #0 to host www.googleapis.com left intact
* Hostname www.googleapis.com was found in DNS cache
*   Trying 74.125.130.95...
* Connected to www.googleapis.com (74.125.130.95) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
* Server certificate: *.googleapis.com
* Server certificate: Google Internet Authority G2
* Server certificate: GeoTrust Global CA
> PUT /upload/youtube/v3/videos?part=status%2Csnippet&uploadType=resumable&upload_id=AEnB2Ur4P0Fpf3GsMWAoc6dUIeXmQXuAfdhuIP1jIbQJPyVQm0aqZ0NGuljcT-U0c5hW2wrE-AepZMghHOzpvkUZb-I9zBruAw HTTP/1.1
Host: www.googleapis.com
Accept: */*
content-range: bytes 20971520-22020095/388638417
content-type: application/json; charset=UTF-8
content-length: 1048576
* We are completely uploaded and fine
* Operation timed out after 100000 milliseconds with 0 bytes received
* Closing connection 0

  [Google_IO_Exception]                                                
  Operation timed out after 100000 milliseconds with 0 bytes received  

上传一段时间后,上传似乎会突然停止。我认为这可能是由于服务器的内存限制,所以我升级了EC2实例类型,这解决了这个视频文件的问题,但当上传另一个更大的文件时,同样的事情再次发生。

在这里回答我自己的问题,以防对其他人有所帮助:

诀窍是增加区块大小,以便一次将较大的区块发送到YouTube。解决方案来自这里:

http://www.softwarehorizont.com/2016/03/youtube-api-v3-connection-timeout-on.html