Youtube Oauth 2.0 API 视频上传失败 [英] Youtube Oauth 2.0 API Videos Upload Failed

查看:34
本文介绍了Youtube Oauth 2.0 API 视频上传失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我设法构建了 oauth 2.0 youtube 视频上传,但每次我上传视频时,我都会收到一个请求无效的 HTTP 400 错误.

So i managed to built oauth 2.0 youtube video upload, but everytime i upload a video i get an HTTP 400 ERROR with a invalid request.

但最奇怪的是,视频正在上传到 youtube 时出现:失败(上传中止).

But the weirdest thing is that the video is uploading to youtube while having : Failed (upload aborted).

我没有使用任何框架,因为谷歌还没有任何 oauth 2.0,所以我自己构建了所有代码.

im not using any framework, cause google doesnt have yet any to oauth 2.0, so i built all of my code on my own.

而且我确实设法发送了评论和其他东西......唯一的问题是视频上传本身.

And also i did managed to send comments, and stuff.... the only problem is the video upload itself.

我的代码:

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 Bad Request Server: Build on May 7 2012 18:16:42 (1336439802) Content-Type: text/html;字符集= UTF-8 X-GUploader-UPLOADID:AEnB2Uq7cHcf6rS4bcamu18ChAF3gnKJqsF6U_dk2qB4WR9GhAoTL_-iUejitgead-GH-1fpJcke1z68TAxoopS2vYiGmCW69A日期:星期四,2012年5月10日11点55分24秒GMT杂注:无缓存过期:周五,1990年1月1日00:00:00 GMT缓存-控制:无缓存,无存储,必须重新验证内容长度:15 连接:关闭

The error im getting: HTTP/1.1 400 Bad Request Server: HTTP Upload Server Built on May 7 2012 18:16:42 (1336439802) Content-Type: text/html; charset=UTF-8 X-GUploader-UploadID: AEnB2Uq7cHcf6rS4bcamu18ChAF3gnKJqsF6U_dk2qB4WR9GhAoTL_-iUejitgead-Gh-1fpJcke1z68TAxoopS2vYiGmCW69A Date: Thu, 10 May 2012 11:55:24 GMT Pragma: no-cache Expires: Fri, 01 Jan 1990 00:00:00 GMT Cache-Control: no-cache, no-store, must-revalidate Content-Length: 15 Connection: close

无效请求

谢谢大家!

推荐答案

我注意到的几件事:对 POST 和 Host 标头进行硬编码是一种糟糕的形式,因为 curl 会自动为您处理它们.我怀疑问题的一部分是在 $videoData 和最后一个边界标记之间插入了回车/换行符.这将被解释为视频文件的一部分.您所需要的只是作为行分隔符的换行符.也许回车使视频文件无效?

Couple of things I notice: hard coding the POST and Host headers is poor form, because curl will take care of them automatically for you. I suspect part of the problem is the insertion of the carriage return/line feed between the $videoData and the last boundary marker. That will be interpreted as part of the video file. All you need are line feeds as line separators. Maybe the carriage return renders the video file invalid?

也许 curl_setopt($ch, CURLOPT_VERBOSE, true) 会提供一些启发.

Maybe curl_setopt($ch, CURLOPT_VERBOSE, true) will provide some illumination.

这对我有用(在 Linux 主机上):

This works for me (on a Linux host):

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

这篇关于Youtube Oauth 2.0 API 视频上传失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆