Reputation: 1093
Context I'm working with Android Studio (Java). I want to obtain all the videos of a given playlist (or 50, I will get all the other after).
Problem I see people using url like
https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=PLiEwZfNgb4fVrRzTonlVEMj6DB2Nmzg2M&key=AIzaSyC2_YRcTE9916fsmA0_KRnef43GbLzz8m0
but I don't know how to implement this in Java. I follow some tuto and I got a way to get information totally different like :
YouTube.Search.List query;
query = youtube.search().list("id,snippet");
query.setKey(MY_API_KEY);
query.setMaxResults((long)20);
query.setType("video");
query.setFields("items(id/videoId,snippet/title,snippet/description,snippet/thumbnails/default/url)");
And I really don't understand how do I get something else than a search. Most of documentation is in english only...
EDIT Ok, so I continued to try, I think I got a near solution, but I got an error.
private YouTube youtube;
private YouTube.PlaylistItems.List playlistItemRequest;
private String PLAYLIST_ID = "PLiEwZfNgb4fVrRzTonlVEMj6DB2Nmzg2M";
public static final String KEY = "AIzaSyC2_YRcTE9916fsmA0_KRnef43GbLzz8m0";
// Constructor
public YoutubeConnector(Context context)
{
youtube = new YouTube.Builder(new NetHttpTransport(),
new JacksonFactory(), new HttpRequestInitializer()
{
@Override
public void initialize(HttpRequest hr) throws IOException {}
}).setApplicationName(context.getString(R.string.app_name)).build();
}
public List<VideoItem> result()
{
List<PlaylistItem> playlistItemList = new ArrayList<PlaylistItem>();
try
{
/* HERE MUST BE MY PROBLEM ! */
playlistItemRequest = youtube.playlistItems().list("snippet");
playlistItemRequest.setPlaylistId(PLAYLIST_ID);
playlistItemRequest.setFields("items(id/videoId,snippet/title,snippet/description,snippet/thumbnails/default/url),nextPageToken,pageInfo");
playlistItemRequest.setKey(KEY);
String nextToken = "";
do {
playlistItemRequest.setPageToken(nextToken);
PlaylistItemListResponse playlistItemResult = playlistItemRequest.execute();
playlistItemList.addAll(playlistItemResult.getItems());
nextToken = playlistItemResult.getNextPageToken();
} while (nextToken != null);
}catch(IOException e)
{
Log.d("YC", "Could not initialize: "+e);
}
//[...]
}
Here is the error I got :
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"location" : "fields",
"locationType" : "parameter",
"message" : "Invalid field selection videoId",
"reason" : "invalidParameter"
} ],
"message" : "Invalid field selection videoId"
}
EDIT 2 Thanks to : Martijn Woudstra. Correct line was :
playlistItemRequest = youtube.playlistItems().list("snippet,contentDetails");
//[...]
playlistItemRequest.setFields("items(snippet/title,snippet/description,snippet/thumbnails/default/url,contentDetails/videoId),nextPageToken,pageInfo");
//[...]
videoItem.setId(item.getContentDetails().getVideoId());
Upvotes: 3
Views: 3925
Reputation: 8975
I know that is an old question but It is important to identify which resources are we using to understand how to get the proper information. There are many resources in the YouTube API v3, but we usually use the search
, video
, playlist
and playlistItems
.
According to the documentation the following JSON structure shows the format of a playlistItems
resource:
{
"kind": "youtube#playlistItem",
"etag": etag,
"id": string,
"snippet": {
"publishedAt": datetime,
"channelId": string,
"title": string,
"description": string,
"thumbnails": {
(key): {
"url": string,
"width": unsigned integer,
"height": unsigned integer
}
},
"channelTitle": string,
"playlistId": string,
"position": unsigned integer,
"resourceId": {
"kind": string,
"videoId": string,
}
},
"contentDetails": {
"videoId": string,
"startAt": string,
"endAt": string,
"note": string,
"videoPublishedAt": datetime
},
"status": {
"privacyStatus": string
}
}
From this structure, we may suppose that there are three ways to get the videoId
. But first it is important to know how we going to define the PARTS and the FIELDS of the resource.
To define the PARTS we use this code:
YouTube.PlaylistItems.List list = youtube.playlistItems().list("snippet");
In the previous line, "snippet"
identifies a property that contains numerous fields (or child properties), including the title
, description
, position
, and resourceId
, so when we set "snippet"
the API's response will contain all of those child properties.
Now, we also can limit the previous properties if we define the FIELDS. For example, in this code:
list.setFields("items(id/videoId,snippet/title,snippet/description," +
"snippet/thumbnails/default/url)");
If we call list.execute()
, it will show an error because we didn't define id
in the PARTS properties. Also, according to the JSON structure, id
is a String and does not contains videoId
as a child property. Ah!, but we can extract videoId
from the resourceId
? -Well, the answers is YES/NO. -Why so? Come on Teo, the JSON structure shows it clearly. -Yes, I can see that, but the documentation says:
If the
snippet.resourceId.kind
property's value isyoutube#video
, then this property will be present and its value will contain the ID that YouTube uses to uniquely identify the video in the playlist.
This means that sometimes may not be available. -Then, how we can get the videoId
? -Well, we can add id
or contentDetails
to the PARTS resources. If we add id
then defines fields like this:
YouTube.PlaylistItems.List list = youtube.playlistItems().list("id,snippet");
list.setFields("items(id,snippet/title,snippet/description," +
"snippet/thumbnails/default/url)");
If we add contentDetails
then defines fields like this:
YouTube.PlaylistItems.List list = youtube.playlistItems()
.list("snippet,contentDetails");
list.setFields("items(contentDetails/videoId,snippet/title,snippet/description," +
"snippet/thumbnails/default/url)");
I hope this helps you guys.
Upvotes: 3
Reputation: 131
id/videoId
doesnt exist.
There is an id
and a snippet/resourceId/videoId
.
So my guess is your setfields aren't right.
Upvotes: 2