2013-08-22 3 views
1

YouTube API v3은 끔찍한 기록이 있습니다. 이미 여러 번 버그를 여러 번보고했지만 아무도 반응하지 않습니다. 아직이 API를 사용하여 미리보기 이미지를 업로드해야합니다. 가이드 상태 : 모든썸네일 업로드 YouTube API v3 실패

POST https://www.googleapis.com/youtube/v3/thumbnails/set

Auth scopes:

Parameters:

  • videoId: string The videoId parameter specifies a YouTube video ID for which the custom video thumbnail is being provided.

첫째 - URL이 잘못입니다. https://www.googleapis.com/upload/youtube/v3/thumbnails/set이어야합니다.

final HttpResponse<String> response = Unirest.post("https://www.googleapis.com/upload/youtube/v3/thumbnails/set") 
        .header("Content-Type", "application/octet-stream") 
        .header("Authorization", accountService.getAuthentication(account).getHeader()) 
        .field("videoId", videoid) 
        .field("thumbnail", thumbnail) 
        .asString(); 

수신 된 응답 :

{ 
"error": { 
    "errors": [ 
    { 
    "domain": "global", 
    "reason": "required", 
    "message": "Required parameter: videoId", 
    "locationType": "parameter", 
    "location": "videoId" 
    } 
    ], 
    "code": 400, 
    "message": "Required parameter: videoId" 
} 
} 

방법이 될 수 이제 다음 코드, 그것은 Unirest 사용? videoId가 설정되었습니다! 이미이 API 부분을 사용 해본 사람이 있습니까?

나는이 나에게이 오류가 발생합니다

Unirest.post("https://www.googleapis.com/upload/youtube/v3/thumbnails/set?videoId=" + videoid) 
        .header("Content-Type", "application/octet-stream") 
        .header("Authorization", accountService.getAuthentication(account).getHeader()) 
        .field("mediaUpload", thumbnail) 
        .asString(); 

요청을 변경할 수 있습니다

:

{ 
"error": { 
    "errors": [ 
    { 
    "domain": "global", 
    "reason": "backendError", 
    "message": "Backend Error" 
    } 
    ], 
    "code": 503, 
    "message": "Backend Error" 
} 
} 

편집 : 이브라힘 Ulukaya (참조 가이드에서 원래 URL을 게시 한 URL과 같은 요청) :

{ 
"error": { 
    "errors": [ 
    { 
    "domain": "global", 
    "reason": "wrongUrlForUpload", 
    "message": "Uploads must be sent to the upload URL. Re-send this request to https://www.googleapis.com/upload/youtube/v3/thumbnails/set" 
    } 
    ], 
    "code": 400, 
    "message": "Uploads must be sent to the upload URL. Re-send this request to https://www.googleapis.com/upload/youtube/v3/thumbnails/set" 
} 
} 

답변

2

우리는 문제를 파헤쳤습니다. 라이브러리를 사용하지 않으려는 경우 다음 단계를 따르십시오.

1) POST https://www.googleapis.com/upload/youtube/v3/thumbnails/set?videoId=VIDEO_ID&uploadType=resumable 빈 몸

2) 위치의 URL 돌아갈와 : 이미지/PNG와의 축소판 : 그 콘텐츠 형식으로 URL에 대한 응답의 헤더 및 POST를 본문

+0

라이브러리를 사용하고 싶지만 불완전한/작동하지 않는 라이브러리를 사용할 수 없습니다 : D. 이것을 시험하지는 않았지만, 이것이 지금 고쳐 졌다고 믿습니다. –

+0

위대한 대답; 이것이 공식 문서에 추가 될 수 있습니까? – spiralman

+0

물론, 나는 그것을 추가 할 수있는 좋은 곳을 발견 할 것이다. –

1

URL이 수정됩니다.

맞춤 미리보기 이미지를 설정하려면 채널에 대한 특정 권한이 있어야합니다.

예제 코드에는 PHPPython 예제가 있습니다.

다음은 자바 코드입니다. 필자가 작성하고 테스트 한 것입니다.

/* 
* Copyright (c) 2013 Google Inc. 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 
* in compliance with the License. You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software distributed under the License 
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 
* or implied. See the License for the specific language governing permissions and limitations under 
* the License. 
*/ 

package com.google.api.services.samples.youtube.cmdline.youtube_cmdline_uploadthumbnail_sample; 

import com.google.api.client.auth.oauth2.Credential; 
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; 
import com.google.api.client.extensions.java6.auth.oauth2.FileCredentialStore; 
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; 
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; 
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; 
import com.google.api.client.googleapis.json.GoogleJsonResponseException; 
import com.google.api.client.googleapis.media.MediaHttpUploader; 
import com.google.api.client.googleapis.media.MediaHttpUploaderProgressListener; 
import com.google.api.client.http.HttpTransport; 
import com.google.api.client.http.InputStreamContent; 
import com.google.api.client.http.javanet.NetHttpTransport; 
import com.google.api.client.json.JsonFactory; 
import com.google.api.client.json.jackson2.JacksonFactory; 
import com.google.api.services.youtube.YouTube; 
import com.google.api.services.youtube.YouTube.Thumbnails.Set; 
import com.google.api.services.youtube.model.ThumbnailSetResponse; 
import com.google.common.collect.Lists; 

import java.io.BufferedInputStream; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.List; 

/** 
* This sample uploads and sets a custom thumbnail for a video by: 
* 
* 1. Uploading a image utilizing "MediaHttpUploader" 2. Setting the uploaded image as a custom 
* thumbnail to the video via "youtube.thumbnails.set" method 
* 
* @author Ibrahim Ulukaya 
*/ 
public class UploadThumbnail { 

    /** 
    * Global instance of the HTTP transport. 
    */ 
    private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); 

    /** 
    * Global instance of the JSON factory. 
    */ 
    private static final JsonFactory JSON_FACTORY = new JacksonFactory(); 

    /** 
    * Global instance of Youtube object to make all API requests. 
    */ 
    private static YouTube youtube; 

    /* Global instance of the format used for the image being uploaded (MIME type). */ 
    private static String IMAGE_FILE_FORMAT = "image/png"; 



    /** 
    * Authorizes the installed application to access user's protected data. 
    * 
    * @param scopes list of scopes needed to run youtube upload. 
    */ 
    private static Credential authorize(List<String> scopes) throws IOException { 

    // Load client secrets. 
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, 
     new InputStreamReader(UploadThumbnail.class.getResourceAsStream("/client_secrets.json"))); 

    // Checks that the defaults have been replaced (Default = "Enter X here"). 
    if (clientSecrets.getDetails().getClientId().startsWith("Enter") 
     || clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) { 
     System.out.println(
      "Enter Client ID and Secret from https://code.google.com/apis/console/?api=youtube" 
      + "into youtube-cmdline-uploadthumbnail-sample/src/main/resources/client_secrets.json"); 
     System.exit(1); 
    } 

    // Set up file credential store. 
    FileCredentialStore credentialStore = new FileCredentialStore(
     new File(System.getProperty("user.home"), ".credentials/youtube-api-uploadthumbnail.json"), 
     JSON_FACTORY); 

    // Set up authorization code flow. 
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
     HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialStore(credentialStore) 
     .build(); 

    // Build the local server and bind it to port 8080 
    LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8080).build(); 

    // Authorize. 
    return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user"); 
    } 

    /** 
    * This is a very simple code sample that looks up a user's channel, then features the most 
    * recently uploaded video in the bottom left hand corner of every single video in the channel. 
    * 
    * @param args command line args (not used). 
    */ 
    public static void main(String[] args) { 

    // An OAuth 2 access scope that allows for full read/write access. 
    List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube"); 

    try { 
     // Authorization. 
     Credential credential = authorize(scopes); 

     // YouTube object used to make all API requests. 
     youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(
      "youtube-cmdline-addfeaturedvideo-sample").build(); 

     // Get the user selected video Id. 
     String videoId = getVideoIdFromUser(); 
     System.out.println("You chose " + videoId + " to upload a thumbnail."); 

     // Get the user selected local image file to upload. 
     File imageFile = getImageFromUser(); 
     System.out.println("You chose " + imageFile + " to upload."); 

     InputStreamContent mediaContent = new InputStreamContent(
      IMAGE_FILE_FORMAT, new BufferedInputStream(new FileInputStream(imageFile))); 
     mediaContent.setLength(imageFile.length()); 

     // Create a request to set the selected mediaContent as the thumbnail of the selected video. 
     Set thumbnailSet = youtube.thumbnails().set(videoId, mediaContent); 

     // Set the upload type and add event listener. 
     MediaHttpUploader uploader = thumbnailSet.getMediaHttpUploader(); 

     /* 
     * Sets whether direct media upload is enabled or disabled. True = whole media content is 
     * uploaded in a single request. False (default) = resumable media upload protocol to upload 
     * in data chunks. 
     */ 
     uploader.setDirectUploadEnabled(false); 

     MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() { 
     @Override 
     public void progressChanged(MediaHttpUploader uploader) throws IOException { 
      switch (uploader.getUploadState()) { 
      case INITIATION_STARTED: 
       System.out.println("Initiation Started"); 
       break; 
      case INITIATION_COMPLETE: 
       System.out.println("Initiation Completed"); 
       break; 
      case MEDIA_IN_PROGRESS: 
       System.out.println("Upload in progress"); 
       System.out.println("Upload percentage: " + uploader.getProgress()); 
       break; 
      case MEDIA_COMPLETE: 
       System.out.println("Upload Completed!"); 
       break; 
      case NOT_STARTED: 
       System.out.println("Upload Not Started!"); 
       break; 
      } 
     } 
     }; 
     uploader.setProgressListener(progressListener); 

     // Execute upload and set thumbnail. 
     ThumbnailSetResponse setResponse = thumbnailSet.execute(); 

     // Print out returned results. 
     System.out.println("\n================== Uploaded Thumbnail ==================\n"); 
     System.out.println(" - Url: " + setResponse.getItems().get(0).getDefault().getUrl()); 

    } catch (GoogleJsonResponseException e) { 
     System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode() + " : " 
      + e.getDetails().getMessage()); 
     e.printStackTrace(); 

    } catch (IOException e) { 
     System.err.println("IOException: " + e.getMessage()); 
     e.printStackTrace(); 
    } 
    } 

    /* 
    * Prompts for a video ID from standard input and returns it. 
    */ 
    private static String getVideoIdFromUser() throws IOException { 

    String title = ""; 

    System.out.print("Please enter a video Id to update: "); 
    BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in)); 
    title = bReader.readLine(); 

    if (title.length() < 1) { 
     // If nothing is entered, exits 
     System.out.print("Video Id can't be empty!"); 
     System.exit(1); 
    } 

    return title; 
    } 

    /* 
    * Prompts for the path of the image file to upload from standard input and returns it. 
    */ 
    private static File getImageFromUser() throws IOException { 

    String path = ""; 

    System.out.print("Please enter the path of the image file to upload: "); 
    BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in)); 
    path = bReader.readLine(); 

    if (path.length() < 1) { 
     // If nothing is entered, exits 
     System.out.print("Path can not be empty!"); 
     System.exit(1); 
    } 

    return new File(path); 
    } 
} 
+0

질문을 업데이트했습니다. 초기 URL에 대한 응답이 위에 게시됩니다. 어떤 다른 권한이 필요합니까? –

+0

그래서 Google을 싫어하는 이유 : 우수한 지원을 제공하는 Google 그룹이 폐쇄되었습니다. 멋진 사이트 인 stackoverflow를 사용해야하지만 youtube-api에 대한 경험이있는 사용자는 극소수입니다. Java 샘플은 여전히 ​​온라인 상태가 아닙니다. 전체 문서에 게시하고 게시 한 URL이 유효하지 않습니다. 이슈 트래커가 무시됩니다. Ibrahim, 더 나은 작동 버그 수정 API를 얻으려면 이전 방법으로 글자를 써야합니까? (주의를 요하는 섬네일뿐 아니라). 또는 @Google을 시작해야합니까? –

+0

새 샘플을 추가했습니다. –

0

주어진 답은 정확하지 않습니다.당신이 본문에 이미지없이이 URL에 게시 할 경우 : "400 : mediaBodyRequired"

:

https://www.googleapis.com/upload/youtube/v3/thumbnails/set?videoId=VIDEO_ID&uploadType=resumable

는이 오류가 발생합니다이 오류에 유튜브 문서에 설명되어

이 페이지의 하단 :

https://developers.google.com/youtube/v3/docs/thumbnails/set

등 :

"요청에 이미지 콘텐츠가 없습니다."

많은 설명서가 있지만 (categoryId를 생각해보십시오.) Ibrahim이 게시 한 첫 번째 솔루션을 시도하여 오류가 발생했기 때문에 설명서가 다 죽었습니다. 그는 신체의 이미지 데이터를 제공하지 않겠다고 말했지만, 문서와 내 연구 결과는 정확히 반대입니다.

해결 방법은 포함 된 이미지 본문이있는이 URL에 게시하는 것입니다. 그렇게 할 때, 나는이 응답을받은 :

{ "종류": "유튜브 # thumbnailSetResponse", "ETAG": "\"kYnGHzMaBhcGeLrcKRx6PAIUosY/lcDPfygjJkG-yyzdBp0dKhY2xMY \ "", "항목": [{ "기본" { "url": "//i.ytimg.com/vi/fyBx3v1gmbM/default.jpg", "width": 120, "height": 90}, "medium": { "url": "// i. "width": 320, "height": 180}, "high": { "url": "//i.ytimg.com/vi/fyBx3v1gmbM/hqdefault. jpg ","width ": 480,"height ": 360},"standard ": {"url ":"//i.ytimg.com/vi/fyBx3v1gmbM/sddefault.jpg ","width ": 640, height ": 480},"maxres ": {"url ":"//i.ytimg.com/vi/fyBx3v1gmbM/maxresdefault.jpg ","width ": 1280,"height ": 720}}]}

불행히도 실제로 미리보기 이미지가 변경되지는 않지만 API Ser와 관련된 문제라고 생각합니다. ver과 썸네일 처리 큐잉 성공한 응답을 리턴합니다. 축소판이 왜 바뀌지 않는지는 알 수 없습니다.