0

我正在尝试使用 com.google.api.services.youtube.YouTube 类从 java 应用程序获取我的 youtube 频道列表。.

首先,我启用了服务帐户凭据(https://console.developers.google.com > Credentials)并启用了以下 api:-YouTube Analytics API -YouTube Data API -Analytics API

为了调用 Youtube 服务,我使用以下代码创建了一个 Credential 对象。


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

private static Credential authorize() throws Exception 
{

List<String> scopes = new ArrayList<String>();
    scopes.add("https://www.googleapis.com/auth/youtube");  
    scopes.add("https://www.googleapis.com/auth/yt-analytics.readonly");
    scopes.add("https://www.googleapis.com/auth/youtube.readonly");
    scopes.add("https://www.googleapis.com/auth/youtubepartner-channel-audit");

    GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
        .setJsonFactory(JSON_FACTORY)
        .setServiceAccountPrivateKeyFromP12File(new File("C://file.privatekey.p12"))
        .setServiceAccountId("xxxx-yyyyyyyyyyyyyy@developer.gserviceaccount.com")
        .setServiceAccountScopes(scopes)
        .build();
        return credential;
  }

之后我打电话给 Youtube 服务来获取我的频道


/** 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 general YouTube API requests. */
  private static YouTube youtube;

  /** Global instance of YoutubeAnalytics object to make analytic API requests. */
  private static YouTubeAnalytics analytics;


public String getDefaultChannelId(){
      try{
      Credential credential = authorize();
      // YouTube object used to make all non-analytic API requests.
      youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
        .setApplicationName("API Project")
        .build();

      YouTube.Channels.List channelRequest = youtube.channels().list("id,snippet");
      channelRequest.setMine(true);
      channelRequest.setMaxResults(50L);
    channelRequest.setFields("items(id,snippet/title,contentDetails,status,kind,etag,auditDetails)");
      ChannelListResponse channels = channelRequest.execute();

      System.out.println(channels.getItems());

      // List of channels associated with user.
      List<Channel> listOfChannels = channels.getItems();

      // Grab default channel which is always the first item in the list.
      Channel defaultChannel = listOfChannels.get(0);
      String channelId = defaultChannel.getId();
      return channelId;
    }catch(Exception ex){
      ex.printStacktrace();
    }
}

授权码似乎没有任何问题。问题在于 getDefaultChannelId() 方法,该方法返回 id 为 UC9i22sTxrX0IQk4AkT_Og3w 的频道。我尝试使用浏览器使用 tha url 导航到我的 youtube 频道:http ://www.youtube.com/channel/UC9i22sTxrX0IQk4AkT_Og3w 但该频道不存在..

我用来打印通道结果的行“System.out.println(channels.getItems());” 显示以下 json 字符串。

[{"etag":"\"BDC7VThyM9nfoSQm1_kOyhtJTEw/yJvLzly7DMctrvFV5drOtgksadM\"","id":"UC9i22sTxrX0IQk4AkT_Og3w","kind":"youtube#channel","snippet":{"title":""}}

由于某种原因,youtube 服务没有返回特定凭证对象的正确频道列表。但为什么????

4

1 回答 1

3

您不能将服务帐户与 Youtube API 一起使用:https ://developers.google.com/youtube/v3/guides/moving_to_oauth#service_accounts 。Youtube API 应该会引发服务帐户错误,但显然不会。

您应该创建一个类型为 Installed Application 的客户端 ID,然后为您的用户检索刷新令牌 ( https://developers.google.com/accounts/docs/OAuth2InstalledApp ) 并使用此令牌创建凭据。

这是一个示例(将 clientId、clientSecret、refreshToken 和 accessToken 存储在您喜欢的任何位置,一旦您对其保密,则应缓存令牌响应):

private String clientId;
private String clientSecret;
private String refreshToken;
private String accessToken;
private TokenResponse tokenResponse;

private Credential createCredential() {
    final GoogleCredential.Builder builder = new GoogleCredential.Builder();
    builder.setTransport(HTTP_TRANSPORT);
    builder.setJsonFactory(JSON_FACTORY);
    builder.setClientSecrets(clientId, clientSecret);
    builder.addRefreshListener(new CredentialRefreshListener() {
        @Override
        public void onTokenResponse(final Credential credential,
                final TokenResponse tokenResponse) throws IOException {
            this.tokenResponse = tokenResponse;
        }

        @Override
        public void onTokenErrorResponse(final Credential credential,
                final TokenErrorResponse tokenErrorResponse)
                throws IOException {
            this.tokenResponse = null;
            // trace error
        }
    });
    return builder.build();
}

private YouTube getYoutube() {
    final Credential credential = createCredential();
    if (this.tokenResponse == null) {
        credential.setAccessToken(this.accessToken);
        credential.setRefreshToken(this.refreshToken);
    } else {
        credential.setFromTokenResponse(this.tokenResponse);
    }

    final YouTube youtube = new YouTube.Builder(HTTP_TRANSPORT,
            JSON_FACTORY, credential).setApplicationName("*****").build();
    return youtube;
}
于 2014-07-28T16:12:50.000 回答