Загрузка видео на Youtube с помощью curl и api v3

Я бы загрузил видео с помощью YouTube API v3 с curl в PHP, как описано здесь: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.

кто может помочь?

4 ответов


к сожалению, у нас пока нет конкретного примера загрузки YouTube API v3 с PHP, но мой общий совет:

  • использовать клиентская библиотека PHP вместо cURL.
  • базовый код на написано для API диска. Поскольку YouTube API v3 имеет общую инфраструктуру API с другими API Google, примеры таких действий, как загрузка файлов, должны быть очень похожи на разные сервисы.
  • посмотри пример Python для конкретных метаданных, которые должны быть установлены в загрузке YouTube v3.

В общем, есть много вещей, неправильных с вашим кодом cURL, и я не могу пройти через все шаги, которые потребовались бы, чтобы исправить это, поскольку я думаю, что использование клиентской библиотеки PHP-гораздо лучший вариант. Если вы уверены, что хотите использовать cURL, я передам кому-то другому конкретное руководство.


обновленная версия: теперь с пользовательским url-адресом загрузки и отправкой метаданных с процессом загрузки. Весь процесс требует 2 запросов:

  1. сделать пользовательскую загрузки

    сначала сделайте запрос POST для url-адреса загрузки:

    "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.

кроме того, из-за пользовательского местоположения загрузки эта версия может возобновляться, хотя мне это еще не нужно.


скрипт 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']

я смог загрузить видео на свой канал на 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 }')

auth_header="Authorization: Bearer $access_token"
upload_url=$(curl -I -X POST -H "$auth_header" "$api_url"|awk -F ' |\r'  '/loc/{print }'); curl -v -X POST --data-binary "@" -H "$auth_header" "$upload_url"

относятся к этой аналогичный вопрос о том, как получить пользовательские значения переменных.