Php 使用curl和api v3在Youtube上上传视频

Php 使用curl和api v3在Youtube上上传视频,php,curl,upload,youtube-api,Php,Curl,Upload,Youtube Api,我将使用Youtube API v3和PHP中的curl上传视频,如下所述: 我有这个函数 function uploadVideo($file, $title, $description, $tags, $categoryId, $privacy) { $token = getToken(); // Tested function to retrieve the correct AuthToken $video->snippet['title'] = $

我将使用Youtube API v3和PHP中的curl上传视频,如下所述:

我有这个函数

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上传YouTube API v3的具体例子,但我的一般建议是:

  • 用卷曲代替卷曲
  • 基于为驱动器API编写的代码。因为YouTube API v3与其他Google API共享一个通用的API基础设施,所以在不同的服务中,上传文件等操作的示例应该非常相似
  • 请查看,以获取需要在YouTube v3上载中设置的特定元数据

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

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

  • 获取自定义上载位置

    首先,发出上传url的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"}
            }
        }
    
    从这个请求中,您应该会得到一个在标题中带有“location”字段的响应

  • 发布到自定义位置以发送文件

    对于上载,您需要1个标题:

    "Authorization": "Bearer {YOUR_ACCESS_TOKEN}"
    
    并将该文件作为数据/正文发送

  • 如果您通读了他们的客户机是如何工作的,您会发现,如果返回的错误代码为500、502、503或504,他们建议您重试。显然,您希望在重试和最大重试次数之间有一段等待时间。它每次都在我的系统中工作,尽管我使用python&urllib2而不是cURL

    此外,由于自定义上载位置,此版本具有上载可恢复功能,尽管我还需要它。

    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']
    
    #categoryId是电影和动画的“1”
    #要获取所有类别,请执行以下操作:https://www.googleapis.com/youtube/v3/videoCategories?part=snippet®ionCode={2字符区域代码}&key={app key}
    meta={'snippet':{'categoryId':'1',
    “描述”:描述,
    “标记”:[“任何标记”],
    “title”:您的_title},
    'status':{'privacyStatus':'private'如果private否则'public'}
    param={'key':{GOOGLE\u API\u key},
    “部分”:“代码段,状态”,
    “uploadType”:“可恢复”}
    标头={'Authorization':'Bearer{}'。格式(令牌),
    “内容类型”:“应用程序/json”}
    #获取位置url
    重试次数=0
    重试次数=1
    
    在重试时,我可以使用以下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"
    
    #/垃圾箱/垃圾箱
    #将给定的视频文件上载到YouTube频道。
    cid\u base\u url=“apps.googleusercontent.com”
    客户机_id=“.cid_base_url”
    client_secret=“”
    刷新令牌=“”
    令牌\u url=”https://accounts.google.com/o/oauth2/token"
    api_基础_url=”https://www.googleapis.com/upload/youtube/v3"
    api_url=“$api_base_url/视频?上传类型=可恢复&部分=片段”
    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=“授权:持有人$access_令牌”
    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”
    

    有关如何获取自定义变量值的类似问题,请参阅。

    谢谢!我的尝试是做一些更轻的东西,但我会尝试Google_YoutubeService.php中的官方Google Library。我找不到调用所需插入方法的函数。所有方法都用于列出(频道、播放列表、视频…)我必须等待更新版本的库?我决定使用Zend_Gdata_YouTube和第二版本的API,因为缺少我需要的方法。如果您愿意,您可以使用Zend客户端库和v2的API,当然。这里有一个用于API v3的方法,不过:我在上传后设置参数时也有问题请求,您是否仍然使用2个请求来上载和更新元数据?我不再使用了。我已将此方法更改为更稳定的方法,我将编辑新方法的答案。@ChadBefus是标题或正文的三个参数部分,还是作为查询的URL的一部分?@ChadBefus我刚刚得到响应“未找到”“。你知道怎么了吗?@ChadBefus我只是想说声谢谢你,先生。我一直在关注这篇文章,作为从我的iOS应用程序向YouTube发送视频帖子请求的指南,它非常有效。谢谢:)