Youtube Data API v3 - Get video feeds of auto-generated channels - youtube-api

I want to use auto-generated channel Ids as example below...
GET https://www.googleapis.com/youtube/v3/channels?part=snippet&id=UCrfjym-5AEUY2QzXsddRIQA&fields=items(id%2Csnippet)&key={YOUR_API_KEY}
...to access their video contents. But seems I cannot make use of the part: 'snippet,contentDetails', or filter:'uploads' filtering method as I use for getting normal user channel Ids before grabbing their playlistItems. Is there a simple method to display video feed or playlist contents of an auto-generated channel? I use the gapi.client instead of the url. Thx for guidance.

FINAL UPDATE:
Here is my solution for auto-generated Topic-based channel ids, since I'm using
gapi.client, here's what works (relevant code only - URL samples below):
function requestUserUploadsPlaylistId(pageToken) {
var itemId = $("#YOUR-TEXT-INPUT").val(CHANNEL-ID); // Topic-based channel Id
var request = gapi.client.youtube.playlists.list({ // Use playlists.list
channelId: itemId, // Return the specified channel's playlist
part: 'snippet',
filter: 'items(id)' // This gets what you only need, the playlist Id
});
request.execute(function(response) {
playlistId = response.result.items[0].id;
requestVideoPlaylist(playlistId, pageToken); // Now call function to get videos
});
}
function requestVideoPlaylist(playlistId, pageToken) {
var requestOptions = {
playlistId: playlistId,
part: 'id,snippet',
maxResults: 6
};
var request = gapi.client.youtube.playlistItems.list(requestOptions);
request.execute(function(response) { // playlistItems.list is used here
. . .
Here's the URL sample of auto-generated Topic-based Id which grabs its playlist id:
GET https://www.googleapis.com/youtube/v3/playlists?part=snippet&channelId=HC9m3exs6zk1U&fields=items%2Fid&key={YOUR_API_KEY} // Outputs sample playlist Id: LP9m3exs6zk1U
Now here's the URL sample using that playlist Id to get the videos from the auto-generated Topic-based channel Id:
GET https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=5&playlistId=LP9m3exs6zk1U&key={YOUR_API_KEY} // Outputs video data you want.
Remember, Topic-based channel Ids come in different lengths, the above samples support current available lengths.
Hope This Helps!

Related

How to get Youtube channel details using Youtube data API if channel has custom url

I would like to fetch details of a YouTube channel which has a custom URL, like https://www.youtube.com/c/pratiksinhchudasamaisawesome.
Custom channel URLs follow this format: https://www.youtube.com/c/{custom_channel_name}.
I can fetch the details of YouTube channels by Channel ID and username without any issues. Unfortunately, I need to use the custom channel URL which is the only time I encounter this issue.
I developed my app few months ago, and the custom channel URL was working up until a few days ago. Now, the YouTube data API does not return anything for the YouTube custom channel URL if I try get details using their custom name.
To get the details of this channel: https://www.youtube.com/user/thenewboston, for example, the request would be:
GET https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=thenewboston&key={YOUR_API_KEY}
Response
200
- SHOW HEADERS -
{
"kind": "youtube#channelListResponse",
"etag": "\"zekp1FB4kTkkM-rWc1qIAAt-BWc/8Dz6-vPu69KX3yZxVCT3-M9YWQA\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#channel",
"etag": "\"zekp1FB4kTkkM-rWc1qIAAt-BWc/KlQLDlUPRAmACwKt9V8V2yrOfEg\"",
"id": "UCJbPGzawDH1njbqV-D5HqKw",
"snippet": {
"title": "thenewboston",
"description": "Tons of sweet computer related tutorials and some other awesome videos too!",
"publishedAt": "2008-02-04T16:09:31.000Z",
"thumbnails": {
"default": {
"url": "https://yt3.ggpht.com/--n5ELY2uT-U/AAAAAAAAAAI/AAAAAAAAAAA/d9JvaIEpstw/s88-c-k-no-rj-c0xffffff/photo.jpg"
},
"medium": {
"url": "https://yt3.ggpht.com/--n5ELY2uT-U/AAAAAAAAAAI/AAAAAAAAAAA/d9JvaIEpstw/s240-c-k-no-rj-c0xffffff/photo.jpg"
},
"high": {
"url": "https://yt3.ggpht.com/--n5ELY2uT-U/AAAAAAAAAAI/AAAAAAAAAAA/d9JvaIEpstw/s240-c-k-no-rj-c0xffffff/photo.jpg"
}
},
"localized": {
"title": "thenewboston",
"description": "Tons of sweet computer related tutorials and some other awesome videos too!"
}
}
}
]
}
It works perfectly.
Now we have to get details of these channels:
https://www.youtube.com/c/eretteretlenek
https://www.youtube.com/c/annacavalli
Then we get:
GET https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=annacavalli&key={YOUR_API_KEY}
Response
200
- SHOW HEADERS -
{
"kind": "youtube#channelListResponse",
"etag": "\"zekp1FB4kTkkM-rWc1qIAAt-BWc/TAiG4jjJ-NTZu7gPKn7WGmuaZb8\"",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 5
},
"items": [
]
}
This can be easily reproduced using the API explorer.
Simplest solution, using API only, is to just use Search:list method of YouTube Data API. From what I can tell (mind you, this is from my own research, official docs say nothing on this subject!), if you search using the custom URL component, with "channel" result type filter and "relevance" (default) sorting, first result should be what you're looking for.
So the following query gets 16 results, with the first one being the one you're looking for. Same goes for all other custom channel URLs I tested, so I think this is the most reliable way of doing this.
GET https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&q=annacavalli&type=channel&key={YOUR_API_KEY}
The other idea is just scraping YouTube page at the custom URL, where you can find ChannelID in one of the meta tags in HTML code. But that's ineffective, unreliable and AFAIK in violation of YouTube terms of use.
Edit: Well, it returns no results for smaller channels, so it's not reliable at all.
Workaround
Expanding off of #jkondratowicz answer, using the search.list in combination with channels.list you can most of the time resolve the channel from the custom url value.
The channel resource has a property customUrl so if we take the channels from the search.list results and get that extra detail about them from the channels.list it is possible to try and match up the custom url value with the customUrl property.
A working JavaScript method here, just replace the api key with your own. Though it is still not perfect, this tries the first 50 channels returned. More could be done with paging and pageTokens.
function getChannel(customValue, callback) {
const API_KEY = "your_api_key"
$.ajax({
dataType: "json",
type: "GET",
url: "https://www.googleapis.com/youtube/v3/search",
data: {
key: API_KEY,
part: "snippet",
q: customValue,
maxResults: 50,
order: 'relevance',
type: 'channel'
}
}).done(function (res) {
const channelIds = [];
for (let i=0; i<res.items.length; i++) {
channelIds.push(res.items[i].id.channelId);
}
$.ajax({
dataType: "json",
type: "GET",
url: "https://www.googleapis.com/youtube/v3/channels",
data: {
key: API_KEY,
part: "snippet",
id: channelIds.join(","),
maxResults: 50
}
}).done(function (res) {
if (res.items) {
for (let i=0; i<res.items.length; i++) {
const item = res.items[i];
if (item.snippet.hasOwnProperty("customUrl") && customValue.toLowerCase() === item.snippet.customUrl.toLowerCase()) {
callback(item);
}
}
}
}).fail(function (err) {
logger.err(err);
});
}).fail(function (err) {
logger.err(err);
});
}
A good example using it with https://www.youtube.com/c/creatoracademy.
getChannel('creatoracademy', function (channel) {
console.log(channel);
});
However, it is still unreliable as it depends on if the channel comes back in the original search.list query. It seems possible that if the custom channel url is too generic that the actual channel may not come back in the search.list results. Though this method is much more reliable then depending on the first entry of search.list to be the right one as search results don't always come back in the same order.
Issue
There has been at least three feature requests to Google in the past year requesting for an additional parameter for this custom url value but they were all denied as being infeasible. Apparently it is too difficult to implement. It was also mentioned as not being on their roadmap.
https://issuetracker.google.com/issues/174903934 (Dec 2020)
https://issuetracker.google.com/issues/165676622 (Aug 2020)
https://issuetracker.google.com/issues/161718177 (Jul 2020)
Resources
Google: Understand your channel URLs
Search: list | YouTube Data API
Channels: list | YouTube Data API
An alternative way is to use a parser (PHP Simple HTLM DOM parser, for the example below : PHP Simple HTML DOM Parser) :
<?php
$media_url = 'https://www.youtube.com/c/[Channel name]';
$dom = new simple_html_dom();
$html = $dom->load(curl_get($media_url));
if (null !== ($html->find('meta[itemprop=channelId]',0))) {
$channelId = $html->find('meta[itemprop=channelId]',0)->content;
}
?>
(Using Youtube api's "search" method has a quota cost of 100)
It is possible the get the channel ID by the video ID, that can help depends on the need fo your application.
Here are an example:
$queryParams = [
'id' => 'UcDjWCEvZLM'
];
$response = $service->videos->listVideos('snippet', $queryParams)->getItems();
$channelId = $response[0]->snippet['channelId'];
$channelTitle = $response[0]->snippet['channelTitle'];
I'm assuming that only channels with videos uploaded by the channel owner will be of interest. This is accidentally convenient since my method doesn't work with 0 video channels anyway.
Given a channel's url, my method will get the beautifulsoup HTML object of that channel's videos tab, and scrape the HTML to find the unique channel id. It'll then reconstruct everything and give back the channel url with the unique channel id.
your_channel_url = 'Enter your channel url here'
channel_url = your_channel_url.strip("https://").strip("featured")
https = "https://"
channel_vids_tab = https + channel_url + '/videos'
import requests
from bs4 import BeautifulSoup
source = requests.get(channel_vids_tab).text
soup = BeautifulSoup(source, "html.parser")
a = soup.find('body').find('link')['href']
channel_id = a.split('/')[-1]
print(a)
print(channel_id)
This method bypass the headache of one channel having different /user and /c url (for example /user/vechz and /c/vechz vs /c/coreyms and /user/schafer5 leading to the same page). Though you need to manually enter the url at first, it can be easily automated.
I'm also fairly confident that if a channel has 0 videos, this line of thinking can also apply for the playlist created BY the channel owner, and only needs a little tweaking. But if there's 0 videos or playlist created by the channel ... who knows
As #jkondratowicz noted, there is no way to reliably get this from the API as small channels do not return at the top of the search results.
So here is a JS example of how to get the channel id by extracting it from the HTML channel page (h/t #Feign'):
export const getChannelIdForCustomUrl = async (customUrl: string) => {
const page = await axios.get(`https://www.youtube.com/c/${customUrl}`)
const chanId = page.data.match(/channelId":"(.*?)"/)[1]
return chanId
}
Here is the .NET approach to convert custom Channel name/URL to a ChannelId using search API as mentioned in the accepted answer.
// https://www.youtube.com/c/TheQ_original/videos
// they call custom URL ?
// https://stackoverflow.com/questions/37267324/how-to-get-youtube-channel-details-using-youtube-data-api-if-channel-has-custom
// https://developers.google.com/youtube/v3/docs/channels#snippet.customUrl
// GET https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&q=annacavalli&type=channel&key={YOUR_API_KEY}
//
/// <summary>
/// Returns ChannelID from old "Custom Channel Name/URL"
/// Support the following URLs format
/// https://www.youtube.com/c/MakeYourOWNCreation
/// </summary>
/// <param name="ChannelName"></param>
/// <returns></returns>
// 20220701
public async Task<string> CustomChannelNameToChannelId(String ChannelName)
{
var YoutubeService = YouTubeService();
//
List<YouTubeInfo> VideoInfos = new List<YouTubeInfo>();
//
// -) Step1: Retrieve 1st page of channels info
var SearchListRequest = YoutubeService.Search.List("snippet");
SearchListRequest.Q = ChannelName;
SearchListRequest.Type = "channel";
//
SearchListRequest.MaxResults = 50;
// Call the search.list method to retrieve results matching the specified query term.
var SearchListResponse = await SearchListRequest.ExecuteAsync();
// According to the SO post the custom channel will be the first one
var searchResult = SearchListResponse.Items[0];
//
// Return Channel Information, we care to obtain ChannelID
return searchResult.Id.ChannelId;
}

Google Youtube API Search doesn't retrieve all videos in the channel

I have to retrieve all video of my channel with Youtube API.
All videos are published on Youtube and I can see them correctly.
I tried to make the request directly from this page:
https://developers.google.com/youtube/v3/docs/search/list
and this is the example request:
GET http s://www.googleapis.com/youtube/v3/search?part=snippet&channelId=myChannelID&maxResults=50&key={YOUR_API_KEY}
Request doesn't retrieve all videos, it returns only 7 on the total of 9.
All videos have the same configuration. Missing videos are always the same.
If I use the video API passing the ID of one of those videos excluded from the search response, it returns a correct response and it belong correctly to my channel:
https://developers.google.com/youtube/v3/docs/videos/list#try-it
Someone can help me?
thank you in advance
Francesco
The answer to "How do I obtain a list of all videos in a channel using the YouTube Data API v3?" here may be what you need. Look especially at the video linked to in the answer.
To summarize, to get all the uploads from a channel, you need to get the items from the uploads playlist for the channel using playlistItems.list on that playlist's ID rather than calling search.list on the channel ID.
Try this two-step approach:
Get the ID of your channel's uploads playlist using the channels.list API call: GET https://www.googleapis.com/youtube/v3/channels?part=contentDetails&id={YOUR_CHANNEL_ID}&key={YOUR_API_KEY}
Get the videos from the uploads playlist using the playlistItems.list call: GET https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=3&playlistId={YOUR_PLAYLIST_ID}&key={YOUR_API_KEY}
try this
async static Task<IEnumerable<YouTubeVideo>> GetVideosList(Configurations configurations, string searchText = "", int maxResult = 20)
{
List<YouTubeVideo> videos = new List<YouTubeVideo>();
using (var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = configurations.ApiKey
}))
{
var searchListRequest = youtubeService.Search.List("snippet");
searchListRequest.Q = searchText;
searchListRequest.MaxResults = maxResult;
searchListRequest.ChannelId = configurations.ChannelId;
searchListRequest.Type = "video";
searchListRequest.Order = SearchResource.ListRequest.OrderEnum.Date;// Relevance;
var searchListResponse = await searchListRequest.ExecuteAsync();
foreach (var responseVideo in searchListResponse.Items)
{
videos.Add(new YouTubeVideo()
{
Id = responseVideo.Id.VideoId,
Description = responseVideo.Snippet.Description,
Title = responseVideo.Snippet.Title,
Picture = GetMainImg(responseVideo.Snippet.Thumbnails),
Thumbnail = GetThumbnailImg(responseVideo.Snippet.Thumbnails)
});
}
return videos;
}
}

Youtube api v3 Get list of user's videos

With Youtube api v2, there's easy way to get videos. Just send a query like this:
http://gdata.youtube.com/feeds/mobile/videos?max-results=5&alt=rss&orderby=published&author=OneDirectionVEVO
The Youtube api v2 also has an interactive demo page for building query:
http://gdata.youtube.com/demo/index.html
With Youtube api v3, I don't know the corresponding way. Please point me the way with api v3.
Thank you!
The channels#list method will return a JSON with some information about the channel, including the playlist ID for the "uploads" playlist:
https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=OneDirectionVEVO&key={YOUR_API_KEY}
With the playlist ID you can get the videos with the playlistItems#list method:
https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=UUbW18JZRgko_mOGm5er8Yzg&key={YOUR_API_KEY}
You can test those at the end of the documentation pages.
This should do it. This code just gets and outputs the title but you can get any details you want
// Get Uploads Playlist
$.get(
"https://www.googleapis.com/youtube/v3/channels",{
part : 'contentDetails',
forUsername : 'USER_CHANNEL_NAME',
key: 'YOUR_API_KEY'},
function(data) {
$.each( data.items, function( i, item ) {
pid = item.contentDetails.relatedPlaylists.uploads;
getVids(pid);
});
}
);
//Get Videos
function getVids(pid){
$.get(
"https://www.googleapis.com/youtube/v3/playlistItems",{
part : 'snippet',
maxResults : 20,
playlistId : pid,
key: 'YOUR_API_KEY'},
function(data) {
var results;
$.each( data.items, function( i, item ) {
results = '<li>'+ item.snippet.title +'</li>';
$('#results').append(results);
});
}
);
}
<!--In your HTML -->
<ul id="results"></ul>
If quota cost is a consideration, it may be beneficial to follow this simple algorithm.
First grab the data from https://www.youtube.com/feeds/videos.xml?channel_id=... This is a simple XML feed which will give you the video ID's, but you cannot specify further 'parts' (stats, etc).
Using the video ID's from that list, do a query on the /videos API endpoint which allows for a comma-separated-list of video ID's which should only result in 1 quota cost, plus 0-2 for any additional part parameters. As #chrismacp points out, using the /search endpoint is simpler but has a quota cost of 100, which can add up quickly.
There is a resource consideration here (cpu, memory, etc) as you are making a second call, but I believe in many scenarios this can be a useful method.
Things have changed alot in V3 of the API. Here is a video that walks you through the v3 API calls needed to get a list of the videos uploaded in a given channel, with live demos using the API Explorer.
YouTube Developers Live: Getting a Channel's Uploads in v3 - https://www.youtube.com/watch?v=RjUlmco7v2M
In case it helps anyone here this is what I discovered and so far seems to be working well for me. I am authenticating the member via OAuth 2.0 prior to making this request, which will give me the authenticated members videos. As always, your personal mileage may vary :D
curl https://www.googleapis.com/youtube/v3/search -G \
-d part=snippet \
-d forMine=true \
-d type=video \
-d order=date \
-d access_token={AUTHENTICATED_ACCESS_TOKEN}
The equivalent of the request you posted is actually a search in the 3.0 api, not a playlist request. It's easier too to do it that way. You do need to excange the username for a channel ID though.
ex. GET https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=UUGhCVGZ0ZSpe5hJHWyiLwHA&key={YOUR_API_KEY}
Here is some code using the offical Google APIs Node library (https://github.com/google/google-api-nodejs-client)
const readJson = require("r-json");
const google = require('googleapis');
const Youtube = google.youtube('v3');
// DONT store your credentials in version control
const CREDENTIALS = readJson("/some/directory/credentials.json");
let user = "<youruser>";
let numberItems = 10;
let channelConfig = {
key: CREDENTIALS.youtube.API_KEY,
part: "contentDetails",
forUsername: user
};
Youtube.channels.list(channelConfig, function (error, data) {
if (error) {
console.log("Error fetching YouTube user video list", error);
return;
}
// Get the uploads playlist Id
let uploadsPlaylistId = data.items[0].contentDetails.relatedPlaylists.uploads;
let playlistConfig = {
part : 'snippet',
maxResults : size,
playlistId : uploadsPlaylistId,
key: CREDENTIALS.youtube.API_KEY
};
// Fetch items from upload playlist
Youtube.playlistItems.list(playlistConfig, function (error, data) {
if (error) {
console.log("Error fetching YouTube user video list", error);
}
doSomethingWithYourData(data.items);
});
});
An alternative method may be to get the playlists for the currently oauth authenticated user via: property mine=true
where the oauth access_token is retrieved following authentification:
https://developers.google.com/youtube/v3/guides/authentication
https://www.googleapis.com/youtube/v3/playlists?part=id&mine=true&access_token=ya29.0gC7xyzxyzxyz
Please don't use playlistitems.list if you want to get the videos of playlist with more then 300 videos. You can try it live in google link "https://developers.google.com/youtube/v3/docs/playlistItems/list" in "Try it" section. It returns undefined.
I have used in my project also. It returns undefined only.
In PHP:
I used pageToken attribute to go to all page of playlist.I hope it can help you.
//step 1: get playlist id
$response = file_get_contents("https://www.googleapis.com/youtube/v3/channels?key={$api_key}&forUsername={$channelName}&part=contentDetails");
$searchResponse = json_decode($response,true);
$data = $searchResponse['items'];
$pid = $data[0]['contentDetails']['relatedPlaylists']['uploads'];
//step 2: get all videos in playlist
$nextPageToken = '';
while(!is_null($nextPageToken)) {
$request = "https://www.googleapis.com/youtube/v3/playlistItems?key={$api_key}&playlistId={$pid}&part=snippet&maxResults=50&pageToken=$nextPageToken";
$response = file_get_contents($request);
$videos = json_decode($response,true);
//get info each video here...
//go next page
$nextPageToken = $videos['nextPageToken'];
}
In node.js, it can be achieved with following code.
Requires authKey and channelId as options object parameter.
cb callback is called after data is fetched.
async function fetchChannelInfo(options) {
const channelUrl = `https://www.googleapis.com/youtube/v3/channels?part=contentDetails,statistics&id=${
options.channelId
}&key=${options.authKey}`;
const channelData = await axios.get(channelUrl);
return channelData.data.items[0];
}
function fetch(options, cb) {
fetchChannelInfo(options).then((channelData) => {
options.playlistId = channelData.contentDetails.relatedPlaylists.uploads;
const paylistUrl = `https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=${
options.playlistId
}&key=${options.authKey}`;
axios
.get(paylistUrl)
.then((response) => {
const payloadData = ;
const videoList = [];
response.data.items.forEach((video) => {
videoList.push({
publishedAt: video.snippet.publishedAt,
title: video.snippet.title,
thumbnails: thumbnails,
videoId: video.snippet.resourceId.videoId,
});
});
cb(null, videoList);
})
.catch((err) => {
cb(err, null);
});
});
}
Note: axios is used for RESTful requests. To install
npm install axios
$.get(
"https://www.googleapis.com/youtube/v3/channels",{
part: 'snippet,contentDetails,statistics,brandingSettings',
id: viewid,
key: api},
function(data){
$.each(data.items, function(i, item){
channelId = item.id;
pvideo = item.contentDetails.relatedPlaylists.uploads;
uploads(pvideo);
});
});
Uploads Function can be
function uploads(pvideo){
$.get(
"https://www.googleapis.com/youtube/v3/playlistItems",{
part: 'snippet',
maxResults:12,
playlistId:pvideo,
key: api},
function(data){
$.each(data.items, function(i, item){
videoTitle = item.snippet.title;
videoId = item.id;
description = item.snippet.description;
thumb = item.snippet.thumbnails.high.url;
channelTitle = item.snippet.channelTitle;
videoDate = item.snippet.publishedAt;
Catagoryid = item.snippet.categoryId;
cID = item.snippet.channelId;
})
}
);
}
function tplawesome(e,t){res=e;for(var n=0;n<t.length;n++){res=res.replace(/\{\{(.*?)\}\}/g,function(e,r){return t[n][r]})}return res}
$(function() {
$(".form-control").click(function(e) {
e.preventDefault();
// prepare the request
var request = gapi.client.youtube.search.list({
part: "snippet",
type: "video",
q: encodeURIComponent($("#search").val()).replace(/%20/g, "+"),
maxResults: 20,
order: "viewCount",
publishedAfter: "2017-01-01T00:00:00Z"
});
// execute the request
request.execute(function(response) {
var results = response.result;
$("#results").html("");
$.each(results.items, function(index, item) {
$.get("tpl/item.html", function(data) {
$("#results").append(tplawesome(data, [{"title":item.snippet.title, "videoid":item.id.videoId ,"descrip":item.snippet.description ,"date":item.snippet.publishedAt ,"channel":item.snippet.channelTitle ,"kind":item.id.kind ,"lan":item.id.etag}]));
});
});
resetVideoHeight();
});
});
$(window).on("resize", resetVideoHeight);
});
function resetVideoHeight() {
$(".video").css("height", $("#results").width() * 9/16);
}
function init() {
gapi.client.setApiKey("YOUR API KEY .... USE YOUR KEY");
gapi.client.load("youtube", "v3", function() {
// yt api is ready
});
}
Check the Complete code here https://thecodingshow.blogspot.com/2018/12/youtube-search-api-website.html

Why Youtube trhows a NullPointerException when trying to get the editlink

String atomXml = "<?xml version='1.0'?>" +
"<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005' gd:fields='yt:accessControl' xmlns:yt='http://gdata.youtube.com/schemas/2007'>" +
"<yt:accessControl action='comment' permission='denied'/>"+
"<yt:accessControl action='rate' permission='denied'/></entry>";
System.out.println("Dsiabling Comments and Rating");
GDataRequest request = service.createPatchRequest(new URL(entry.getEditLink().getHref()));
request.getRequestStream().write(atomXml.getBytes("UTF-8"));
request.execute();
System.out.println("Dsiabling Comments and Rating COMPLETED");
In the above code entry is a VideoEntry which was retuned by uploading a video to YouTube. But when I try the code it throws a null pointer exception. Any fix for this. And If there is any other way of setting the comments and rating disabled its fine as well. I do the following once the Video is published.
String updateUrl = "https://gdata.youtube.com/feeds/api/users/default/uploads/"+videoId;
VideoEntry _entry = service.getEntry(new URL(updateUrl), VideoEntry.class);
VideoEntry vToDel = service.getEntry(new URL(_entry.getEditLink().getHref()), VideoEntry.class);
vToDel.delete();
If you want to delete or update a video you cannot take it directly from edit link of the uploaded VideoEntry. You need to query for a new video entry using the same video id. And use that to update or delete.

Get LIKED youtube videos via API

I know how to get the count of 'liked' videos using the YouTube API, but I want to get a list of those videos.
After reading the docs, I think it can be done by getting the 'liked' playlist, but I do not know exactly how.
Can I get the 'liked' video list through the Javascript API?
If you're using v3 of the API, then you can get your liked video list. First, do a call to your channels feed, like this:
https://www.googleapis.com/youtube/v3/channels?part=contentDetails&mine=true&key={YOUR_API_KEY}
Then, in the response, you'll have a list of related playlists -- one will be keyed "likes." Take that playlist ID and request its items feed:
https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId={PLAYLIST_ID}&key={YOUR_API_KEY}
If you don't use v3 of the API, you probably won't have a lot of success in getting the liked videos.
As of 2020, the /videos endpoint lets you filter directly for liked videos, e.g.:
GET https://www.googleapis.com/youtube/v3/videos?myRating=like&part=snippet
Authorization: Bearer <oauth token>
If you pass the following arguments to playlistItems.list, you can get the liked videos' playlist associated with the authorized acccount.
auth: "your_auth_key"
playlistId: "LL"
Here's a code snippet from the script I ran to get the liked videos in a text file.
Note: I used the helper code provided in the YouTube API Documentation to get the authkey and pass it to my function.
// get all the liked videos by a channel
async function get_liked_playlist(authkey){
fs.writeFile("./output/"+"all_liked_videos"+".txt", "\n"+time_stamp, { flag: 'a+' }, e => console.log(e) );
let nextPageToken_ = null;
let text__ = "";
let i = 0;
do {
await API.playlistItems.list({
key: process.env.API_KEY,
auth: authkey,
part: "snippet",
maxResults: 50, // 50 is the max value
playlistId: "LL",
pageToken: nextPageToken_
})
.then(res => {
let results = res.data.items;
nextPageToken_ = res.data.nextPageToken;
results.forEach(item => {
// console.log(`Title: ${item.snippet.title}\tURL: https://youtu.be/${item.snippet.resourceId.videoId}`)
i++;
text__ += "\nTitle: "+item.snippet.title+"\tURL: https://youtu.be/"+item.snippet.resourceId.videoId;
});
console.log("items done: "+i+"\tnextPageToken: "+nextPageToken_);
})
.then( fs.writeFile("./output/"+"all_liked_videos"+".txt", text__ , { flag: 'a+' }, e => { if(e) console.log("error with fs\t"+e); }) )
.then( text__ = "" )
.catch( e => console.log("error here\t" + e) )
} while (nextPageToken_ != null)
if(text__.length>1) fs.writeFile("./output/"+"all_liked_videos"+".txt", text__ , { flag: 'a+' }, e => { if(e) console.log("error with fs\t"+e); });
}

Resources