Php Youtube Oauth 2.0 API视频上载失败
所以我设法构建了OAuth2.0YouTube视频上传,但每次我上传视频时,我都会收到一个HTTP 400错误,请求无效 但最奇怪的是,视频上传到youtube时出现了:失败(上传中止) 我没有使用任何框架,因为谷歌还没有任何到OAuth2.0的框架,所以我自己构建了所有的代码 而且我还设法发送了评论和其他东西。。。。唯一的问题是视频上传本身 我的代码:Php Youtube Oauth 2.0 API视频上载失败,php,api,oauth,youtube,Php,Api,Oauth,Youtube,所以我设法构建了OAuth2.0YouTube视频上传,但每次我上传视频时,我都会收到一个HTTP 400错误,请求无效 但最奇怪的是,视频上传到youtube时出现了:失败(上传中止) 我没有使用任何框架,因为谷歌还没有任何到OAuth2.0的框架,所以我自己构建了所有的代码 而且我还设法发送了评论和其他东西。。。。唯一的问题是视频上传本身 我的代码: public function uploadVideo($video, $title, $description, $category, $k
public function uploadVideo($video, $title, $description, $category, $keywords) {
$url = 'http://uploads.gdata.youtube.com/feeds/api/users/FacebookDevelopersIL/uploads';
$boundary = uniqid();
$accessToken = $this->refreshAccessToken("13", "11313", 'REFRESHTOKEN');
$xmlString = "<?xml version='1.0'?><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'>".$description."</media:description> <media:category scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>".$category."</media:category><media:keywords>".$keywords."</media:keywords></media:group></entry>";
$videoData = file_get_contents($video);
$headers = array(
'POST /feeds/api/users/FacebookDevelopersIL/uploads HTTP/1.1',
'Host: uploads.gdata.youtube.com',
'Authorization: Bearer '.$accessToken,
'GData-Version: 2',
'X-GData-Key: key='.YOUTUBE_SRM_DEVELOPER_KEY,
'Slug: IMG_0047.mp4',
'Content-Type: multipart/related; boundary='.$boundary,
'Content-Length:'.strlen($videoData),
'Connection: close'
);
$postData = "--".$boundary . "\r\n"
."Content-Type: application/atom+xml; charset=UTF-8\r\n\r\n"
.$xmlString . "\r\n"
."--".$boundary . "\r\n"
."Content-Type: video/mp4\r\n"
."Content-Transfer-Encoding: binary\r\n\r\n"
.$videoData . "\r\n"
."--".$boundary . "--";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
$response = curl_exec($ch);
curl_close($ch);
Trace::dump($response); }
公共功能上传视频($video、$title、$description、$category、$keywords){
$url='1http://uploads.gdata.youtube.com/feeds/api/users/FacebookDevelopersIL/uploads';
$boundary=uniqid();
$accessToken=$this->refreshAccessToken(“13”、“11313”、“REFRESHTOKEN”);
$xmlString=“”.$title.”“$description.”“$category.”“$keywords.”;
$videoData=文件获取内容($video);
$headers=数组(
“POST/feeds/api/users/FacebookDevelopersIL/uploads HTTP/1.1”,
'主机:uploads.gdata.youtube.com',
'授权:承载'.$accessToken,
‘GData版本:2’,
“X-GData-Key:Key=”。YOUTUBE_SRM_DEVELOPER_Key,
“Slug:IMG_0047.mp4”,
'内容类型:多部分/相关;边界='。$boundary,
“内容长度:”.strlen($videoData),
'连接:关闭'
);
$postData=“-->$boundary”。\r\n
“内容类型:应用程序/atom+xml;字符集=UTF-8\r\n\r\n”
.$xmlString。“\r\n”
.“-”$boundary。“\r\n”
“内容类型:视频/mp4\r\n”
“内容传输编码:二进制\r\n\r\n”
.$videoData。“\r\n”
“——”$boundary。”——”;
$ch=curl\u init($url);
卷曲设置($ch,卷曲设置桩,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$postData);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch,CURLOPT_头,1);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,0);
$response=curl\u exec($ch);
卷曲关闭($ch);
跟踪::转储($response);}
im获取错误:HTTP/1.1 400错误请求服务器:HTTP上载服务器构建于2012年5月7日18:16:42(1336439802)内容类型:text/html;charset=UTF-8 X-GUploader-UploadID:AEnB2Uq7cHcf6rS4bcamu18ChAF3gnKJqsF6U_dk2qB4WR9GhAoTL_-iUejitgead-Gh-1fpJcke1z68TAxoopS2vYiGmCW69A日期:2012年5月10日星期四11:55:24 GMT Pragma:无缓存过期:1990年1月1日星期五00:00:00 GMT缓存控制:无缓存,无存储,必须重新验证内容长度:15连接:关闭
无效请求
谢谢大家 我注意到两件事:硬编码POST和Host头的形式很糟糕,因为curl会自动为您处理它们。我怀疑部分问题是在$videoData和最后一个边界标记之间插入回车/换行符。这将被解释为视频文件的一部分。您所需要的只是作为行分隔符的行馈送。可能回车会导致视频文件无效 也许curl_setopt($ch,CURLOPT_VERBOSE,true)会提供一些启发 这适用于我(在Linux主机上):
/*
** https://developers.google.com/youtube/2.0/developers_guide_protocol_direct_uploading
*/
私有函数发送到youtube($video文件,$video信息){
//刷新访问令牌
log_msg(“获取访问令牌”);
$response=http\u post($this->config['token\u url',数组(
'client_id'=>this->config['client_id'],
'client_secret'=>this->config['client_secret'],
“刷新令牌”=>$video\u info->刷新密钥,
“授权类型”=>$this->config[“授权类型”]
));
如果($response['http_code']!=200)
抛出新异常(“无法获取访问令牌。”.print_r($response,true));
$authorization=json_decode($response['contents',],true);
//构建多部分上传请求
//api xml,然后是视频文件内容
$boundary=uniqid();
$location='';
如果($video\u info->纬度&&$video\u info->经度)
$location='1
“.$video\u info->纬度。”“.$video\u info->经度。”
';
$content='-'.$boundary'
内容类型:应用程序/atom+xml;字符集=UTF-8
“.$video_info->title”
“.$video_info->说明”
“.$video_info->category”
“.内爆(”,“,$video_info->tags)。”
“.$location。”
--“.$边界。”
内容类型:'.$video\u info->Type'
内容传输编码:二进制
“.file_get_内容($video_文件)。”
--“.$边界。”——”;
$headers=数组(
'授权:'.$Authorization['token\u type'].'.$Authorization['access\u token'],
‘GData版本:2’,
“X-GData-Key:Key=”。$this->config['dev_Key'],
“Slug:”。$video\u info->filename,
'内容类型:多部分/相关;边界=“”.$boundary.”,
“内容长度:”.strlen($Content),
'连接:关闭'
);
//上传视频
log_msg(“发送视频”{$video_info->title},{$video_info->url}”);
$ch=curl\u init($this->config['upload\u url']);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$content);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch,CURLOPT_头,false);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,0);
$response=curl\u exec($ch);
$http\u code=curl\u getinfo($ch,CURLINFO\u http\u code);
卷曲关闭($ch);
如果(!$http_code==201){//除“新条目”之外的其他内容
log_msg(“上传失败:.print_r($response,true));
返回新的SimpleXMLElement();
}
$entry=新的SimpleXMLElement($response);
$yt_link=$entry->link[0]->attributes()->href;
原木
/*
** https://developers.google.com/youtube/2.0/developers_guide_protocol_direct_uploading
*/
private function send_to_youtube($video_file, $video_info) {
// Refresh access token
log_msg("Obtaining access token");
$response = http_post($this->config['token_url'], array(
'client_id' => $this->config['client_id'],
'client_secret' => $this->config['client_secret'],
'refresh_token' => $video_info->refresh_key,
'grant_type' => $this->config['grant_type']
));
if ($response['http_code'] != 200)
throw new Exception("Unable to obtain access token. ".print_r($response, true));
$authorization = json_decode($response['contents'], true);
// Build multi-part upload request
// api xml and then video file contents
$boundary = uniqid();
$location = '';
if ($video_info->latitude && $video_info->longitude)
$location = '
<georss:where>
<gml:Point>
<gml:pos>'. $video_info->latitude .' '. $video_info->longitude .'</gml:pos>
</gml:Point>
</georss:where>';
$content = '--'.$boundary.'
Content-Type: application/atom+xml; charset=UTF-8
<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:yt="http://gdata.youtube.com/schemas/2007"
xmlns:georss="http://www.georss.org/georss"
xmlns:gml="http://www.opengis.net/gml">
<media:group>
<media:title type="plain">'. $video_info->title .'</media:title>
<media:description type="plain">
'. $video_info->description .'
</media:description>
<media:category
scheme="http://gdata.youtube.com/schemas/2007/categories.cat">
'. $video_info->category .'
</media:category>
<media:keywords>'. implode(', ', $video_info->tags) .'</media:keywords>
</media:group>
'. $location .'
</entry>
--'.$boundary.'
Content-Type: '. $video_info->type .'
Content-Transfer-Encoding: binary
'.file_get_contents($video_file).'
--'.$boundary.'--';
$headers = array(
'Authorization: '.$authorization['token_type'].' '.$authorization['access_token'],
'GData-Version: 2',
'X-GData-Key: key='.$this->config['dev_key'],
'Slug: '.$video_info->filename,
'Content-Type: multipart/related; boundary="'.$boundary.'"',
'Content-Length: '.strlen($content),
'Connection: close'
);
// Upload video
log_msg("Sending video '{$video_info->title}', {$video_info->url}");
$ch = curl_init($this->config['upload_url']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (!$http_code == 201) { // Something other than 'New Entry'
log_msg("Upload Failed: ".print_r($response, true));
return new SimpleXMLElement();
}
$entry = new SimpleXMLElement($response);
$yt_link = $entry->link[0]->attributes()->href;
log_msg("Upload Complete: ".$yt_link);
return $entry;
}