2012-11-07 16 views
9

tôi sẽ tải lên một đoạn video bằng cách sử dụng v3 API Youtube với curl trong PHP, như mô tả ở đây: https://developers.google.com/youtube/v3/docs/videos/insertTải lên video trên Youtube sử dụng curl và api v3

Tôi đã chức năng này

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

Nhưng nó trả về số này

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 
     ) 

) 

Tệp này là MP4.

Mọi người đều có thể trợ giúp?

Trả lời

0

Thật không may, chúng tôi không có một ví dụ cụ thể của YouTube cập API v3 từ PHP có sẵn, nhưng lời khuyên chung của tôi là:

  • Sử dụng PHP client library thay vì cURL.
  • Mã cơ sở của bạn trên this example được viết cho API Drive. Vì API YouTube v3 chia sẻ cơ sở hạ tầng API phổ biến với các API Google khác, ví dụ về cách thực hiện những việc như tải tệp lên sẽ rất giống nhau trên các dịch vụ khác nhau.
  • Hãy xem Python example để biết siêu dữ liệu cụ thể cần được đặt trong bản tải lên YouTube v3.

Nói chung, có rất nhiều điều không đúng với mã cURL của bạn và tôi không thể thực hiện tất cả các bước cần thiết để khắc phục sự cố. Tùy chọn. Nếu bạn bị thuyết phục rằng bạn muốn sử dụng cURL thì tôi sẽ trì hoãn người khác để cung cấp hướng dẫn cụ thể.

+0

Cảm ơn! Nỗ lực của tôi là tạo một thứ gì đó nhẹ hơn, nhưng tôi sẽ thử thư viện Google chính thức – genna

+0

Trong Google_YoutubeService.php tôi không thể tìm thấy hàm để gọi phương thức chèn mà tôi cần. Tất cả các phương pháp đều dành cho danh sách (kênh, danh sách phát, video ..) Tôi phải đợi phiên bản mới hơn của thư viện? – genna

+0

Tôi đã quyết định sử dụng Zend_Gdata_YouTube và phiên bản API thứ 2, do thiếu các phương pháp tôi cần cho – genna

16

Phiên bản cập nhật: Bây giờ với url tải lên tùy chỉnh và gửi siêu dữ liệu với quá trình tải lên. Toàn bộ quá trình đòi hỏi 2 yêu cầu:

  1. Nhận một địa điểm upload tùy chỉnh

    Trước tiên, hãy yêu cầu POST cho một địa chỉ tải lên:

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

    Bạn sẽ cần phải gửi 2 tiêu đề:

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

    Bạn cần gửi 3 tham số:

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

    Và bạn sẽ cần phải gửi các siêu dữ liệu cho video trong cơ thể yêu cầu:

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

    Từ yêu cầu này, bạn sẽ nhận được một phản ứng với một lĩnh vực "location" trong tiêu đề.

  2. ĐĂNG đến vị trí tùy chỉnh để gửi tệp.

    Đối với upload bạn cần 1 tiêu đề:

    "Authorization": "Bearer {YOUR_ACCESS_TOKEN}" 
    

    Và gửi nội dung tập tin dữ liệu của bạn/body.

Nếu bạn đọc qua cách khách hàng của họ làm việc, bạn sẽ thấy họ đề nghị thử lại nếu bạn được trả về lỗi của mã 500, 502, 503, hoặc 504. Rõ ràng, bạn sẽ muốn có một khoảng thời gian chờ đợi giữa retries và một số lần thử lại tối đa. Nó hoạt động trong hệ thống của tôi mọi lúc, mặc dù tôi đang sử dụng python & urllib2 thay vì cURL.

Ngoài ra, do vị trí tải lên tùy chỉnh, phiên bản này có thể tải lên có khả năng tiếp tục, mặc dù tôi vẫn chưa cần.

+1

I cũng gặp sự cố khi đặt thông số với yêu cầu tải lên POST, bạn có còn sử dụng 2 yêu cầu để tải lên và cập nhật dữ liệu meta không? – hsafarya

+0

Tôi không còn nữa. Tôi đã thay đổi phương pháp của tôi cho điều này để một cái gì đó ổn định hơn nhiều và tôi sẽ chỉnh sửa câu trả lời của tôi cho phương pháp mới. –

+0

Bất kỳ cập nhật nào về phương pháp mới này? – Mikepote

0

một kịch bản 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

tôi đã có thể tải video lên kênh của tôi trên YouTube bằng Shell Script sau.

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

Tham khảo câu hỏi tương tự this về cách nhận giá trị biến tùy chỉnh của bạn.