2012-11-07 12 views
9

chciałbym przesłać film używając API v3 Youtube z zwinięcie w PHP, jak opisano tutaj: https://developers.google.com/youtube/v3/docs/videos/insertPrześlij film na Youtube za pomocą curl i API v3

Mam ta funkcja

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

Ale zwraca ten

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 
     ) 

) 

Plik jest MP4.

Ktoś może pomóc?

Odpowiedz

0

Niestety, nie mamy konkretny przykład YouTube API v3 przesyłanych z dostępnych w PHP jeszcze, ale moja rada jest ogólny:

  • Użyj PHP client library zamiast cURL.
  • Wpisz swój kod na this example napisany dla interfejsu Drive API. Ponieważ interfejs API YouTube 3 w wersji v3 ma wspólną infrastrukturę API z innymi interfejsami API Google, przykłady takich czynności, jak przesyłanie plików, powinny być bardzo podobne w różnych usługach.
  • Spójrz na Python example, aby poznać konkretne metadane, które należy ustawić w przesłanym filmie YouTube 3.

Ogólnie rzecz biorąc, jest wiele rzeczy niepoprawnych w twoim kodzie cURL i nie mogę przejść przez wszystkie kroki, które trzeba by naprawić, ponieważ myślę, że korzystanie z biblioteki klienta PHP jest o wiele lepsze opcja. Jeśli jesteś przekonany, że chcesz użyć cURL, to odłożę się na kogoś innego w celu zapewnienia konkretnych wskazówek.

+0

Dzięki! Próbowałem zrobić coś lżejszego, ale spróbuję oficjalnej biblioteki Google. – genna

+0

W Google_YoutubeService.php nie mogę znaleźć funkcji wywoływania metody wstawiania, której potrzebuję. Wszystkie metody są na liście (kanały, listy odtwarzania, filmy ..) Muszę czekać na nowszą wersję biblioteki? – genna

+0

Zdecydowałem się użyć Zend_Gdata_YouTube i drugiej wersji API, z powodu braku metod potrzebnych do – genna

16

Zaktualizowana wersja: Teraz z niestandardowym adresem do przesyłania i wysyłaniem metadanych z procesem przesyłania. Cały proces wymaga 2 wnioski:

  1. uzyskać lokalizację zwyczaj wysyłania

    Po pierwsze, upewnij się żądanie POST dla URL przesyłania do:

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

    Trzeba będzie wysłać 2 nagłówki:

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

    Musisz wysłać 3 parametry:

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

    i trzeba będzie wysłać metadanych dla wideo w treści żądania:

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

    Od tego wniosku powinieneś dostać odpowiedź z „location” pola w nagłówkach.

  2. POST do niestandardowej lokalizacji, aby wysłać plik.

    Do przesyłania trzeba 1 nagłówka:

    "Authorization": "Bearer {YOUR_ACCESS_TOKEN}" 
    

    i wysłać plik jako data/ciała.

Jeśli czytasz przez klienta, jak ich prace można zobaczyć zalecają powtórzeń jeśli są zwracane błędy w kodzie 500, 502, 503 lub 504. Oczywiście będziemy chcieli mieć okres oczekiwania między próbami a maksymalna liczba ponownych prób. Działa w moim systemie za każdym razem, ale używam python & urllib2 zamiast cURL.

Ponadto, ze względu na niestandardową lokalizację przesyłania, ta wersja może być ponownie załadowana, chociaż muszę jej jeszcze potrzebować.

+1

I również miałeś problem z ustawianiem parametrów z prośbą o przesłanie POST, czy nadal używasz 2 próśb do przesłania i aktualizacji metadanych? – hsafarya

+0

Już nie. Zmieniłem moją metodę na coś znacznie bardziej stabilnego i zmienię moją odpowiedź na nową metodę. –

+0

Każda aktualizacja tej nowej metody? – Mikepote

0

skrypt 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'] 
0

udało mi się przesłać film na moim kanale na YouTube stosując następujący skrypt.

#!/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" 

Patrz this podobne pytanie jak uzyskać niestandardowe wartości zmiennych.

Powiązane problemy