YouTube API - 直接上传 - 413 请求实体太大 [英] YouTube API - Direct Upload - 413 Request Entity Too Large
问题描述
我一直在尝试通过直接上传将视频上传到 YouTube API.我终于破解了 OAuth 流程并且我有一个有效的令牌.我真的只需要在 YouTube 上做两件事,验证和上传.我没有浏览或使用任何其他功能.用户将视频上传到本网站,然后我将其发送到 YouTube 进行播放.
I've been trying to upload videos to the YouTube API via direct upload. I finally cracked the OAuth Process and I have a valid token. I really only need to do 2 things with YouTube, Authenticate and upload. I am not browsing, or using any of the other functionality. Users upload videos to this website, and I send them to YouTube for playback.
我觉得自己已经完成了 80-90% 的旅程,所以我不想放弃它并使用 Google 提供的 Zend 库.
I feel like I've come 80-90% of the way on my own here, so I do not want to scrap this and use the Zend Library that Google provides.
问题:当我发送请求时,我得到了这个响应:
Problem: When I send the request I get this response:
HTTP/1.1 413 Request Entity Too Large
Content-Type: text/html; charset=UTF-8
Content-Length: 171
Date: Thu, 18 Apr 2013 18:33:22 GMT
Expires: Thu, 18 Apr 2013 18:33:22 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Connection: close
如果我打开警告,我也会收到管道损坏警告,这可能只是尝试通过关闭/拒绝连接上传数据的代码.
If I turn on the warnings, I also get a Broken Pipe warning, which is probably just the code trying to upload the data through the closed/refused connection.
我的要求是:
POST /feeds/api/users/default/uploads HTTP/1.1
Host: gdata.youtube.com Connection: close
User-Agent: PHP Accept-encoding: identity
Authorization: Bearer <TOKEN IS HERE>
GData-Version: 2.0
X-GData-Key: key=<MYKEYISHERE>
Slug: throwing_can.mp4
Content-Type: multipart/related; boundary="5170429d1b193"
Content-Length: 3920610
文件本身被分块并写入流中.
With the file itself chunked and written to the stream.
function ytapi_write_file($handle, $path, $chunksize = 8192){
$filehandle = fopen($path, 'r');
while(!feof($filehandle)){
fwrite($handle, fread($filehandle, $chunksize));
}
fclose($filehandle);
$filehandle = null;
}
function ytapi_write($handle, $request){
fwrite($handle, $request);
return $request;
}
像这样.
ytapi_write($handle, $start); //This writes the header.
ytapi_write_file($handle, $path, 8192); //This writes the file raw/binary.
ytapi_write($handle, $end); //This writes the final boundary.
此外,我将其用于标题信息:
Also, I use this for the header info:
$_header = array(
'Host'=>'gdata.youtube.com',
'Connection'=>'close',
'User-Agent'=>'PHP',
'Accept-encoding'=>'identity'
);
知道我做错了什么吗?如果需要,我可以提供更多信息.我上传的文件有点超过 3MB,这是一个位于相关服务器上的文件.我已确认位置正确.
Any idea as to what I'm doing wrong? I can provide more information if needed. The file I am uploading is a little over 3MB, a file that is sitting on the server in question. I've verified the location is correct.
更改为 uploads.gdata.youtube.com
Changed to uploads.gdata.youtube.com
现在我收到此错误消息:
Now I get this error message:
Host: uploads.gdata.youtube.com
Connection: close
User-Agent: PHP
Accept-encoding: identity
tcp://uploads.gdata.youtube.com:80HTTP/1.1 400 Bad Request
Server: HTTP Upload Server Built on Apr 8 2013 13:06:58 (1365451618)
X-GData-User-Country: US
Content-Type: application/vnd.google.gdata.error+xml
X-GUploader-UploadID: <SOME ID>
Date: Thu, 18 Apr 2013 19:42:14 GMT
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate
Content-Length: 228
Connection: close
推荐答案
这是我的实现:
$data = '<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">
<media:group>
<media:title type="plain">' . $title . '</media:title>
<media:description type="plain">' . trim($description) . '</media:description>
<media:keywords>' . $tags . '</media:keywords>
<media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">Music</media:category>
</media:group>
</entry>';
$headers = array(
'Authorization: GoogleLogin auth=' . $auth,
'GData-Version: 2',
'X-GData-Key: key=<KEY>',
'Slug: ' . basename($videoPath)
);
$tmpfname = tempnam("/tmp", "youtube");
$handle = fopen($tmpfname, "w");
fwrite($handle, $data);
fclose($handle);
$post = array(
'xml' => '@' . $tmpfname . ";type=application/atom+xml",
'video' => '@' . $videoPath . ";type=video/mp4",
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "uploads.gdata.youtube.com/feeds/api/users/default/uploads");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
curl_close($ch);
这篇关于YouTube API - 直接上传 - 413 请求实体太大的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!