2012-05-13 18 views
2

私はoauth 2.0 youtubeビデオアップロードを構築することができましたが、ビデオをアップロードするたびに無効なリクエストでHTTP 400エラーが発生します。Youtube Oauth 2.0 APIビデオアップロード失敗

しかし、奇妙なことは、動画がYouTubeにアップロードされていることです。失敗しました(アップロードが中止されました)。

私は自分のコードをすべて自分で構築していますので、フレームワークを使用していないため、Googleにはまだoauth 2.0がありません。

また、私はコメントを送ってくれました。物事....唯一の問題は、ビデオのアップロード自体です。

マイコード:

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); } 

エラーイム取得:HTTP/1.1 400不正な要求サーバー:2012年5月7日午後06時16分42秒上に構築されたHTTPのアップロードサーバー(1336439802)のContent-Type:text/htmlの; charset = UTF-8 X-GUploader-UploadID:AEnB2Uq7cHcf6rS4bcamu18ChAF3gnKJqsF6U_dk2qB4WR9GhAoTL_-iUejitgead-Gh-1fpJcke1z68TAxoopS2vYiGmCW69A日付:2012年5月10日11:55:24 GMTプラグマ:キャッシュなし期限:金曜日、1990年1月1日00:00:00 GMTキャッシュ-control:キャッシュなし、無店舗、-再検証しなければならないのContent-Length:15接続:近い

無効な要求みんなありがとう

答えて

1

私が気づいたいくつかの事柄:POSTおよびホストヘッダーのハードコーディングは、カールが自動的にあなたのために世話をするので、貧弱な形式です。私は問題の一部が、$ videoDataと最後の境界マーカーの間にキャリッジリターン/ラインフィードを挿入していると思われます。これはビデオファイルの一部として解釈されます。必要なのは、行区切り文字として改行だけです。たぶんキャリッジリターンはビデオファイルを無効にしますか?

多分、curl_setopt($ ch、CURLOPT_VERBOSE、true)はいくらかの照明を提供します。

これは(Linuxホスト上で)私の作品:

/* 
    ** 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; 
    } 
+0

は今(あなたのコードで)この問題を取得イム: 不正な形式のマルチポストを.....それは何を意味するのでしょうか? – Avihay

+0

$ content変数のテキストが正しくアセンブルされていないため、エラーと思われます。私はLinuxホストを使用しています.Windowsホストの場合は、行末が異なり、問題を引き起こす可能性があります。 file_get_contents()が$ video_fileが指すファイルを読み取ることができることを確認しましたか?関数宣言の上のコメントにはリンクがあり、完成した$コンテンツの見た目と必要なヘッダーの例を示しています。たぶんそれとあなたの持っているものをよく比較すれば、その問題が明らかになるでしょう。 – Carl

+0

carl、debianホストを使っているので、osは問題ではありません:)そして私はファイルの内容を取得していることを確認しました、あなたが組み立てた関数のようにすべてがうまくいっています....これは全く変です。 .. – Avihay

関連する問題