【问题标题】:Upload video on Youtube using curl and api v3使用 curl 和 api v3 在 Youtube 上上传视频
【发布时间】:2012-10-27 18:31:30
【问题描述】:

我会在 PHP 中使用带有 curl 的 Youtube API v3 上传视频,如下所述:https://developers.google.com/youtube/v3/docs/videos/insert

我有这个功能

function uploadVideo($file, $title, $description, $tags, $categoryId, $privacy)
{
    $token = getToken(); // Tested function to retrieve the correct AuthToken

    $video->snippet['title']         = $title;
    $video->snippet['description']   = $description;
    $video->snippet['categoryId']    = $categoryId;
    $video->snippet['tags']          = $tags; // array
    $video->snippet['privacyStatus'] = $privacy;
    $res = json_encode($video);

    $parms = array(
        'part'  => 'snippet',
        'file'  => '@'.$_SERVER['DOCUMENT_ROOT'].'/complete/path/to/'.$file
        'video' => $res
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://www.googleapis.com/upload/youtube/v3/videos');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $parms);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$token['access_token']));
    $return = json_decode(curl_exec($ch));
    curl_close($ch);

    return $return;
}

但它会返回这个

stdClass Object
(
    [error] => stdClass Object
        (
            [errors] => Array
                (
                    [0] => stdClass Object
                        (
                            [domain] => global
                            [reason] => badContent
                            [message] => Unsupported content with type: application/octet-stream
                        )

                )

            [code] => 400
            [message] => Unsupported content with type: application/octet-stream
        )

)

文件是 MP4。

有人可以帮忙吗?

【问题讨论】:

    标签: php curl upload youtube-api


    【解决方案1】:

    更新版本:现在使用自定义上传 URL 并通过上传过程发送元数据。整个过程需要2个请求:

    1. 获取自定义上传位置

      首先,对上传网址发出 POST 请求:

      "https://www.googleapis.com/upload/youtube/v3/videos"
      

      您需要发送 2 个标头:

      "Authorization": "Bearer {YOUR_ACCESS_TOKEN}"
      "Content-type": "application/json"
      

      你需要发送3个参数:

      "uploadType": "resumable"
      "part": "snippet, status"
      "key": {YOUR_API_KEY}
      

      您需要在请求正文中发送视频的元数据:

          {
              "snippet": {
                  "title": {VIDEO TITLE},
                  "description": {VIDEO DESCRIPTION},
                  "tags": [{TAGS LIST}],
                  "categoryId": {YOUTUBE CATEGORY ID}
              },
              "status": {
                  "privacyStatus": {"public", "unlisted" OR "private"}
              }
          }
      

      从这个请求中,您应该会在标题中获得带有“位置”字段的响应。

    2. POST 到自定义位置以发送文件。

      对于上传,您需要 1 个标头:

      "Authorization": "Bearer {YOUR_ACCESS_TOKEN}"
      

      并将文件作为您的数据/正文发送。

    如果您仔细阅读他们的客户端的工作方式,您会看到他们建议您在收到代码 500、502、503 或 504 的错误时重试。显然,您希望在重试之间有一个等待期,并达到最大重试次数.它每次都在我的系统中工作,尽管我使用的是 python & urllib2 而不是 cURL。

    另外,由于自定义上传位置,这个版本可以上传恢复,虽然我还没有需要。

    【讨论】:

    • 我也遇到了POST上传请求参数设置的问题,你还用2个请求上传更新元数据吗?
    • 我不再这样做了。我已将我的方法更改为更稳定的方法,我将编辑我对新方法的答案。
    • @ChadBefus 这三个参数是标头或正文的一部分,还是作为查询的 URL 的一部分?
    • @ChadBefus 我只得到“未找到”的响应。你知道怎么回事吗?
    • @ChadBefus 我只是想谢谢你先生。我一直关注这篇文章作为从我的 iOS 应用程序到 YouTube 的视频 POST 请求的指南,它绝对是一种享受。谢谢你:)
    【解决方案2】:

    很遗憾,我们还没有从 PHP 上传 YouTube API v3 的具体示例,但我的一般建议是:

    • 使用 PHP client library 代替 cURL。
    • 您的代码基于为 Drive API 编写的 this example。由于 YouTube API v3 与其他 Google API 共享通用 API 基础架构,因此上传文件等操作的示例在不同服务之间应该非常相似。
    • 查看Python example,了解需要在 YouTube v3 上传中设置的特定元数据。

    一般来说,您的 cURL 代码有很多不正确的地方,我无法完成修复它所需的所有步骤,因为我认为使用 PHP 客户端库是一个更好的选择。如果您确定要使用 cURL,那么我会请其他人提供具体指导。

    【讨论】:

    • 谢谢!我的尝试是做一些更轻的东西,但我会试试 Google 官方库
    • 在 Google_YoutubeService.php 中我找不到调用我需要的插入方法的函数。所有方法都用于列出(频道、播放列表、视频..)我必须等待更新版本的库吗?
    • 由于缺少我需要的方法,我决定使用 Zend_Gdata_YouTube 和 API 的第二版
    • 如果您愿意,当然可以使用 Zend 客户端库和 API 的 v2。不过,这是与 API 的 v3 一起使用的方法:code.google.com/p/google-api-php-client/source/browse/trunk/src/…
    【解决方案3】:

    一个python脚本:

    # categoryId is '1' for Film & Animation
    # to fetch all categories: https://www.googleapis.com/youtube/v3/videoCategories?part=snippet&regionCode={2 chars region code}&key={app key}
    meta =  {'snippet': {'categoryId': '1',
      'description': description,
      'tags': ['any tag'],
      'title': your_title},
      'status': {'privacyStatus': 'private' if private else 'public'}}
    
    param = {'key': {GOOGLE_API_KEY},
             'part': 'snippet,status',
             'uploadType': 'resumable'}
    
    headers =  {'Authorization': 'Bearer {}'.format(token),
               'Content-type': 'application/json'}
    
    #get location url
    retries = 0
    retries_count = 1
    while retries <= retries_count: 
        requset = requests.request('POST', 'https://www.googleapis.com/upload/youtube/v3/videos',headers=headers,params=param,data=json.dumps(meta))
        if requset.status_code in [500,503]:
            retries += 1
        break
    
    if requset.status_code != 200:
        #do something
    
    location = requset.headers['location']
    
    file_data = open(file_name, 'rb').read()
    
    headers =  {'Authorization': 'Bearer {}'.format(token)}
    
    #upload your video
    retries = 0
    retries_count = 1
    while retries <= retries_count:
        requset = requests.request('POST', location,headers=headers,data=file_data)
        if requset.status_code in [500,503]:
            retries += 1
        break
    
    if requset.status_code != 200:
        #do something
    
    # get youtube id
    cont = json.loads(requset.content)            
    youtube_id = cont['id']
    

    【讨论】:

      【解决方案4】:

      我已经能够使用以下 shell 脚本将视频上传到我在 YouTube 上的频道。

      #!/bin/sh
      
      # Upload the given video file to your YouTube channel.
      
      cid_base_url="apps.googleusercontent.com"
      client_id="<YOUR_CLIENT_ID>.$cid_base_url"
      client_secret="<YOUR_CLIENT_SECRET>"
      refresh_token="<YOUR_REFRESH_TOKEN>"
      token_url="https://accounts.google.com/o/oauth2/token"
      api_base_url="https://www.googleapis.com/upload/youtube/v3"
      api_url="$api_base_url/videos?uploadType=resumable&part=snippet"
      
      access_token=$(curl -H "Content-Type: application/x-www-form-urlencoded" -d refresh_token="$refresh_token" -d client_id="$client_id" -d client_secret="$client_secret" -d grant_type="refresh_token" $token_url|awk -F '"' '/access/{print $4}')
      
      auth_header="Authorization: Bearer $access_token"
      upload_url=$(curl -I -X POST -H "$auth_header" "$api_url"|awk -F ' |\r'  '/loc/{print $2}'); curl -v -X POST --data-binary "@$1" -H "$auth_header" "$upload_url"
      

      请参阅this 类似问题,了解如何获取自定义变量值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-30
        • 2012-12-23
        • 1970-01-01
        • 2014-10-13
        • 2012-10-07
        • 2021-01-04
        • 2017-06-14
        • 2014-11-03
        相关资源
        最近更新 更多