我正在尝试从我订阅的频道生成一个视频列表。
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp
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.javanet.GoogleNetHttpTransport;
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.model.PlaylistItemListResponse;
import com.google.api.services.youtube.model.SubscriptionListResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.Collections;
public class ApiExample {
private static final String CLIENT_SECRETS= "client_secret.json";
private static final Collection<String> SCOPES =
Collections.singletonList("https://www.googleapis.com/auth/youtube.readonly");
private static final String APPLICATION_NAME = "Stack Overflow MRE";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/**
* Create an authorized Credential object.
*
* @return an authorized Credential object.
* @throws IOException in the event that the client_secrets.json file is not found
*/
public static Credential authorize(final NetHttpTransport httpTransport) throws IOException {
// Load client secrets.
InputStream in = ApiExample.class.getResourceAsStream(CLIENT_SECRETS);
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY, clientSecrets, SCOPES)
.build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
/**
* Build and return an authorized API client service.
*
* @return an authorized API client service
* @throws GeneralSecurityException, IOException
*/
public static YouTube getService() throws GeneralSecurityException, IOException {
final NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
Credential credential = authorize(httpTransport);
return new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
/**
* Call function to create API service object. Define and
* execute API request. Print API response.
*
* @throws GeneralSecurityException, IOException, GoogleJsonResponseException
*/
public static void main(String[] args)
throws GeneralSecurityException, IOException {
YouTube youtubeService = getService();
// Define and execute the API request
YouTube.Subscriptions.List request = youtubeService.subscriptions()
.list("snippet");
SubscriptionListResponse response = request.setMine(true).setMaxResults(1L).execute();
String channelId = response.getItems().get(0).getSnippet().getResourceId().getChannelId();
YouTube.PlaylistItems.List playListRequest = youtubeService.playlistItems().list("snippet");
PlaylistItemListResponse playlistResponse = playListRequest.setPlaylistId(channelId).execute();
playlistResponse.getItems().forEach(System.out::println);
}
}
我读过获取频道上的所有视频的YouTube API,但是我的问题有点不同,因为我试图从Subscription
而不是从Channel
获取视频列表。
我试图隔离通道ID,以便按照来自Google开发者的视频中关于如何执行此操作的说明进行操作。我用了String channelId = response.getItems().get(0).getSnippet().getResourceId().getChannelId();
然而,当我运行上面的代码(应该以JSON符号从那个通道打印出一个视频列表)时,我看到了这个错误:
Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
"code" : 404,
"errors" : [ {
"domain" : "youtube.playlistItem",
"location" : "playlistId",
"locationType" : "parameter",
"message" : "The playlist identified with the request's <code>playlistId</code> parameter cannot be found.",
"reason" : "playlistNotFound"
} ],
"message" : "The playlist identified with the request's <code>playlistId</code> parameter cannot be found."
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:150)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1067)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at ApiExample.main(ApiExample.java:93)
显然,我没有正确地隔离频道ID,否则我误解了视频。从YouTube订阅中获取视频的正确方法是什么?
编辑
我的主要方法发生了以下变化:
public static void main(String[] args)
throws GeneralSecurityException, IOException {
YouTube youtubeService = getService();
// Define and execute the API request
YouTube.Subscriptions.List request = youtubeService.subscriptions()
.list("snippet")
SubscriptionListResponse response = request.setMine(true).setMaxResults(1L).execute();
String channelId = response.getItems().get(0).getSnippet().getResourceId().getChannelId();
YouTube.Channels.List channelRequest = youtubeService.channels().list("contentDetails");
ChannelListResponse channelResponse = channelRequest.setId(channelId).execute();
String playListID = channelResponse.getItems().get(0).getContentDetails().getRelatedPlaylists().getUploads();
YouTube.PlaylistItems.List playListRequest = youtubeService.playlistItems().list("snippet");
PlaylistItemListResponse playlistResponse = playListRequest.setPlaylistId(playListID).execute();
playlistResponse.getItems().forEach(System.out::println);
}
发布于 2020-09-30 18:09:20
以上代码的问题归结为以下文档条目:
playlistId (字符串)
playlistId
参数指定要检索播放列表项的播放列表的唯一ID。注意,即使这是一个可选参数,每个检索播放列表项的请求都必须为id
参数或playlistId
参数指定一个值。
到目前为止,事情应该是明摆着的:playlistId
是播放列表的ID,因此不能是频道的ID。
但是,要列出一个给定频道的所有上传视频(由其ID标识),必须执行以下操作:
调用PlaylistItems.list
API端点,该端点将参数playlistId
设置为该频道的上传播放列表的ID。
后一个ID可以很容易地通过调用Channels.list
端点来获得,该端点将参数id
设置为您的通道的ID。
然后将上传播放列表ID作为属性值在端点的JSON响应中找到:
items[0].contentDetails.relatedPlaylists.uploads
。
如果转换为Java,该属性路径将成为下面的getter链,以getUploads
结尾
.getItems().get(0).getContentDetails().getRelatedPlaylists().getUploads()
。
请注意,对于给定的频道,您只需要获得上传播放列表ID一次,然后使用它的次数随您的意愿。
通常,频道ID及其相应的上传播放列表ID是由s/^UC([0-9a-zA-Z_-]{22})$/UU\1/
关联的。
https://stackoverflow.com/questions/64142472
复制相似问题