Get a YouTube channel uploaded video list by publish date - youtube

I am aware of similar questions being asked before, but not this exact one, so please bear with me...
I want to reproduce a channel's uploaded videos list as they appear on YouTube's web page (broken into pages and sorted by publish date).
To do this, I am trying to get a list of VideoIDs from a YouTube channel that's sorted by publish date (by YouTube, not my code since there could be 1000's of videos in a playlist and YouTube limits to 50 results per query which can add up when I only want to show the user the first 25 entries).
Initially, I was using this YouTube Data API v3 Search query:
https://www.googleapis.com/youtube/v3/search?key=[APIKey]&channelId=[ChannelID]&part=snippet,id&order=date&type=video&maxResults=25
However, as some of the previous posts on stackoverflow mentioned (YouTube API v3 Search not returning all videos), this method does not guarantee to return all videos and indeed, some videos are missing from the result, making use of this query problematic.
I then saw this google video in some of the posts:
https://www.youtube.com/watch?v=RjUlmco7v2M
In the video, it is explained that you must first get the 'uploads' playlist for a channel (I'm also grabbing the channel's title and thumbnail in this query), which I do using:
https://www.googleapis.com/youtube/v3/channels?key=[APIKEY]&part=snippet,contentDetails&id=[ChannelID]
And once I have the 'uploads' playlist ID, I query:
https://www.googleapis.com/youtube/v3/playlistItems?key=[APIKey]&playlistId=[PlaylistID]&part=snippet,id&order=date&type=video&maxResults=25
However, the returned entries are not sorted by the publish date and according to the documentation (https://developers.google.com/youtube/v3/docs/playlistItems/list), there is no optional "order" parameter associated with this query.
With all these issues in mind, how do I get the first 25 entries of the 'uploads' playlist sorted by publish date without downloading the entire playlist so I can faithfully recreate how the YouTube website is listing videos.

After making some tests and thanks to this answer (and the next answers too) I was able to retrieve the information you need using the YouTube Data API v3 and here is how I made it:
First, in your question you're using the "search" API - since I don't know which criteria you're using in the search request, I omitted it for get direct to get the "upload" playlist id from a given channel_id.
Using the channel_id = UCT2rZIAL-zNqeK1OmLLUa6g (which belongs to "Microsoft HoloLens"), I use the "channels" API for retrieve the uploads playlist id.
Here is the URL request for retrieve the "upload" playlist id from the channel_id previously mentioned:
https://www.googleapis.com/youtube/v3/channels?part=id%2Csnippet%2CcontentDetails&fields=items(contentDetails%2FrelatedPlaylists%2Fuploads%2Csnippet%2Flocalized)&id=UCT2rZIAL-zNqeK1OmLLUa6g&key=<YOUR_API_KEY>
Explanation:
part: set the snippet and contentDetails parts for retrieve the following:
fields: from the snippet part: (localized, description and title) and from the contentDetails part: (relatedPlayLists and uploads).
id: channel_id used in this request.
Here are the results from this request:
{
"items": [
{
"snippet": {
"localized": {
"title": "Microsoft HoloLens",
"description": "The official YouTube channel of Microsoft HoloLens. Transform your world with holograms. Visit HoloLens.com for more info."
}
},
"contentDetails": {
"relatedPlaylists": {
"uploads": "UUT2rZIAL-zNqeK1OmLLUa6g"
}
}
}
]
}
Check the value of the uploads property in the
contentDetails section. This value will be used in the next API request.
You can also check these results in the Google API Explorer demo I prepared for make this request.
Once retrieved the uploads value (as specified in previous lines), now it's time to use the "playlistItems" API for build the following URL:
https://www.googleapis.com/youtube/v3/playlistItems?part=snippet%2CcontentDetails&playlistId=UUT2rZIAL-zNqeK1OmLLUa6g&fields=items(contentDetails(videoId%2CvideoPublishedAt)%2Csnippet%2Ftitle%2Cstatus)&maxResults=25&key=<YOUR_API_KEY>
Explanation:
part: set the snippet and contentDetails parts for retrieve the following:
fields: from the snippet part: (title and status) and from the contentDetails part: (videoId and videoPublishedAt).
playlistId: is the playlistId used in this request - (that is, the uploads value).
maxResults: set to 25.
Here are the results from this request:
{
"items": [
{
"snippet": {
"title": "Microsoft Windows Mixed Reality update | October 2018"
},
"contentDetails": {
"videoId": "00vnln25HBg",
"videoPublishedAt": "2019-01-04T17:43:47.000Z"
}
},
{
"snippet": {
"title": "How to use Spectator View for mobile devices"
},
"contentDetails": {
"videoId": "3fXlPw_FGLg",
"videoPublishedAt": "2018-10-15T17:13:42.000Z"
}
},
{
"snippet": {
"title": "Microsoft HoloLens: Visualizing the next mission to Mars."
},
"contentDetails": {
"videoId": "XVBbJ4EtAQY",
"videoPublishedAt": "2018-07-02T16:30:26.000Z"
}
},
{
"snippet": {
"title": "Microsoft HoloLens: Making mixed reality plug and play."
},
"contentDetails": {
"videoId": "QwXcSekZKWE",
"videoPublishedAt": "2018-06-25T23:25:55.000Z"
}
},
{
"snippet": {
"title": "Microsoft HoloLens | Windows Mixed Reality HMD Exerciser"
},
"contentDetails": {
"videoId": "RU3OMjq_Yic",
"videoPublishedAt": "2018-05-14T16:58:43.000Z"
}
}
]
}
I check the order of the items and they are in sorted by videoPublishedAt value (new to old).
You can also check these results in the try-it funcionality found in the YouTube Data API v3 - official documentation.1
1 For this case, I was unable to use the Google API Explorer (as I used in the first request) because I always got a "backend Error".
{
"error": {
"errors": [
{
"domain": "global",
"reason": "backendError",
"message": "Backend Error"
}
],
"code": 500,
"message": "Backend Error"
}
}
I think this is because the Google API explorer is outdated.
If anyone want to check it out, here is the demo.

I'm also using the playlist ID to get a list of videos, however mine do seem to be sorted by date from newest to oldest. Note that Youtube returns a page token that you can use to get the next 25 (or in my case 50) videos. I'm querying the API this way:
https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&pageToken= not_used_for_first_query&fields=nextPageToken,items(snippet(publishedAt,title,desc ription,thumbnails(default(url)),resourceId(videoId)))&playlistId=uploads_playlist_id&maxResults=50&order=date&key=your_api_key
This gets back in JSON response:
The video title
Publish date
Video description
Youtube URL for video
Video unique ID
Video thumbnail
You can see my working example at https://www.scriptbarrel.com

Related

how do I get youtube shorts from youtube api data v3

I want a way to get YouTube shorts for a specific channel from YouTube API. I looked every where and I couldn't find anything.
Currently I can get a playlist ID for all channel videos with this endpoint:
request = youtube.channels().list(
part="contentDetails",
id=id
)
I also tried these parameters:
request = youtube.channels().list(
part="snippet,contentDetails,statistics,brandingSettings",
id=id
)
So is there a way to get YouTube shorts from a specific channel from YouTube API or any other source if it's available.
One way of detecting if a YouTube video ID is a Short without even using the API is to try a HEAD HTTP request to the /shorts/ version of the URL and see if it redirects you.
https://www.youtube.com/shorts/hKwrn5-7FjQ is a Short and if you visit that URL, you'll get an HTTP status code of 200 and the URL won't change.
https://www.youtube.com/watch?v=B-s71n0dHUk is not a Short, and if you visit https://www.youtube.com/shorts/B-s71n0dHUk, you get a 303 redirect back to the original URL.
Keep in mind, that this behavior might change down the line, but it works as of May 2022.
It seems that once again YouTube Data API v3 doesn't provide a basic feature.
For checking if a given video is a short:
I would recommend you to use my open-source YouTube operational API. Indeed by requesting the JSON document https://yt.lemnoslife.com/videos?part=short&id=VIDEO_ID containing item["short"]["available"] boolean, your problem is solved.
Example of short id: ydPkyvWtmg4
For listing shorts of a channel:
I would recommend you to use my open-source YouTube operational API. Indeed by requesting the JSON document https://yt.lemnoslife.com/channels?part=shorts&id=CHANNEL_ID. The entry item["shorts"] contains the data you are looking for. Note that the pagination works as the one of YouTube Data API v3.
Example of result for channel UC5O114-PQNYkurlTg6hekZw:
{
"kind": "youtube#channelListResponse",
"etag": "NotImplemented",
"items": [
{
"kind": "youtube#channel",
"etag": "NotImplemented",
"id": "UC5O114-PQNYkurlTg6hekZw",
"shorts": [
{
"videoId": "fP8nKVauFwc",
"title": "India: United Nations Counter Terrorism Committee Watch LIVE #shorts",
"thumbnails": [
{
"url": "https:\/\/i.ytimg.com\/vi\/fP8nKVauFwc\/hq720_2.jpg?sqp=-oaymwEYCNAFENAFSFryq4qpAwoIARUAAIhC0AEB&rs=AOn4CLCgJEYgv_msT5pkfWeEEN3VBt4wjg",
"width": 720,
"height": 720
}
],
"viewCount": 3700
},
...
],
"nextPageToken": "4qmFsgLlARIYVUM1TzExNC1QUU5Za3VybFRnNmhla1p3GsgBOGdhU0FScVBBVktNQVFxSEFRcGZRME00VVVGU2IyWnZaMWxqUTJob1ZsRjZWbEJOVkVVd1RGWkNVbFJzYkhKa1dFcHpWa2RqTW1GSFZuSlhibU5SUVZOSlVrTm5PSGhQYWtVeVRtcGplVTE2VlRST2FrVXdUbXBCY1VSUmIweFhWRUl5VGtab1dGSllSbGRNVmtVU0pEWXpOakJoTkRVNUxUQXdNREF0TWpKaE15MDRObUV6TFdRMFpqVTBOMlZqWVRSbFl4Z0I=,CgtuNjFmZlJlR0QxcyiVgICbBg=="
}
]
}
Below is a sample python code to send the HEAD HTTP request.
import requests
def is_short(vid):
url = 'https://www.youtube.com/shorts/' + vid
ret = requests.head(url)
if ret.status_code == 200:
return True
else: # whether 303 or other values, it's not short
return False
I don't know why but I don't get status code 303 whether it's a short or not with axios. So this is another way of checking if it's a short or not.
const isShort = async (videoId) => {
const url = "https://www.youtube.com/shorts/" + videoId
const res = await axios.head(url)
console.log(res.request.res.responseUrl)
// if it's a short it ends with "/shorts/videoId"
// if it's NOT a short it ends "/watch?=videoId"
}
Maybe axios automatically redirects?
You can use the new dimension called 'creatorContentType' from Youtube Analytics and Reports API.
// You can get IDs from PlaylistItems or Search API
const IDs = ["videoID1", "videoID2", "videoID3"];
// Get the analytics data of selected videos based on their IDs
const { data: analyticsData } = await youtubeAnalytics.reports.query({
ids: "channel==MINE",
startDate: "2019-01-01",
// Today's date
endDate: new Date().toISOString().split("T")[0],
metrics: "views",
dimensions: "video,creatorContentType",
filters: `video==${IDs.join(",")}`,
access_token,
});
It basically returns values listed below:
Value
Description
LIVE_STREAM
The viewed content was a YouTube live stream.
SHORTS
The viewed content was a YouTube Short.
STORY
The viewed content was a YouTube Story.
VIDEO_ON_DEMAND
The viewed content was a YouTube video that does not fall under one of the other dimension values.
UNSPECIFIED
The content type of the viewed content is unknown.
Notes:
Don't forget it returns values just for the videos uploaded after 01.01.2019.
Don't forget to add analytics scopes and enable Analytics and Reports API.

YouTube Data API v3 - Problem with categoryId from category list

If I upload a video which has CategoryId 34 (Comedy/Komödie), the API tells me the CategoryId isn't available/supported.
But I got the Categories from YouTube, saved the List in a DB with the following call:
https://developers.google.com/youtube/v3/docs/videoCategories/list?apix_params=%7B%22part%22%3A%22snippet%22%2C%22hl%22%3A%22de_DE%22%2C%22regionCode%22%3A%22DE%22%7D
and this category exists.
So with every "failed upload" my Quota raises. Unfortunately I can upload only 6 videos a day.
Any suggestions?
I checked the Categories, still up-to-date
According to the URL of the request you provided in your question, you're using de_DE as regionCode.
If so, you need to use the id 23 instead - which corresponds to Komödie.
See:
{
"kind": "youtube#videoCategory",
"etag": "\"0UM_wBUsFuT6ekiIlwaHvyqc80M/l3o_qqirQJQvOVhrSz9qa3x9Nxo\"",
"id": "23",
"snippet": {
"channelId": "UCBR8-60-B28hp2BmDPdntcQ",
"title": "Komödie",
"assignable": true
}
}
You can test the results in these demos:
Results of videoCategories.list from Germany "de_DE" in YouTube Official Documentation - "try-it" feature.
Results of videoCategories.list from Germany "de_DE" in Google API Explorer demo.
If you're still sure there's a problem with YouTube Data API, my advice is search whether your problem is already reported on Issue Tracker or report the problem there.

Youtube data api v3 and angular 2+

Im here to ask if it's possible to fully use youtube data api v3 with angular 2+, the documentation just have examples from javascript like authentication, playlist videos, insert a playlist and search of videos (samples)
I'm trying to upload a video, using parameter like:
(gapi.client as any).youtube.videos.insert({
"resource": {
// Video title and description
"snippet": {
"title": "Test",
"description": "Test video upload via YouTube API"
},
"status": {
"privacyStatus": "private"
}
},
"part": "snippet,status,id",
"media": {
"body": video
})
My problem is that even like this, it always return error 404 : "The request does not include the video content.", documentation says the videos needs to be video/* or application/octet-stream, and my video object is a File extended from Blob.
What could i'm possibly doing wrong?
If it's the video file, what I have to do to work?
PS: "(gapi.client as any).youtube" has this any, because youtube is not a property from the interface, its loaded.
Solved
I'm brazilian then I was searching portuguese documentation, that is quite poor, when changed to English, I found 2 archives cors_upload.js and upload_video.js JS samples in the documentation, converted then to typescript and now it works.

get the title on live video in youtube using API YouTube V3

i am using API Live Streaming youtube to retrieve list of live chat messages on youtube video using id_video, exits serveral properties that appear in this resource such as snippet.liveChatId, snippet.displayMessage which i can found them from this ressource,
so my question is how can i get the title on live video in channel youtube which is not for me ?
thanks
You may want to check this documentation. The items[] property will return a list of live streams that match the request criteria.
{
...
},
"items": [
liveStream Resource
]
}
The following JSON structure shows the format of a liveStreams resource:
{
"kind": "youtube#liveStream",
"etag": etag,
"id": string,
"snippet": {
"publishedAt": datetime,
"channelId": string,
"title": string,
"description": string,
"isDefaultStream": boolean
},
...
}

How to get "transcript" in youtube-api v3

I have started using v3 of the YouTube apis on an android device, using the java client library. Some videos that I am interested in have transcripts that I can access on the web interface (like educational videos). Is there a way to access the transcripts, if present, using the v3 apis?
Thanks
I had the same problem with this... and spent like a week looking for a solution until I hit this:
https://stackoverflow.com/questions/10036796/how-to-extract-subtitles-from-youtube-videos
Just do a GET request on: http://video.google.com/timedtext?lang={LANG}&v={VIDEOID}
You don't need any api/oauth/etc. to access this.
With API v3 you can first grab the available transcripts with the snippet:
https://www.googleapis.com/youtube/v3/captions?videoId=U1e2VNtEqm4&part=snippet&key=(my_api_key):
{
"kind": "youtube#captionListResponse",
"etag": "\"DsOZ7qVJA4mxdTxZeNzis6uE6ck/aGHflncRxq1Uz6m1akhrOLUWUqU\"",
"items": [
{
"kind": "youtube#caption",
"etag": "\"DsOZ7qVJA4mxdTxZeNzis6uE6ck/IC7rNKkn3SQNdovFwR6fEabUYnY\"",
"id": "TqXDnlamg84o4bX0q2oaHz4nfWZdyiZMOrcuWsSLyPc=",
"snippet": {
"videoId": "U1e2VNtEqm4",
"lastUpdated": "2016-01-25T21:50:27.142Z",
"trackKind": "standard",
"language": "en-GB",
"name": "",
"audioTrackType": "unknown",
"isCC": false,
"isLarge": false,
"isEasyReader": false,
"isDraft": false,
"isAutoSynced": false,
"status": "serving"
}
},
{
"kind": "youtube#caption",
"etag": "\"DsOZ7qVJA4mxdTxZeNzis6uE6ck/5UP1qPkmq6mzTUaEVnFC8WqjFgU\"",
"id": "TqXDnlamg84o4bX0q2oaHw_Y53ilUWv6vMFbk0RL3XY=",
"snippet": {
"videoId": "U1e2VNtEqm4",
"lastUpdated": "2016-01-25T21:55:07.481Z",
"trackKind": "standard",
"language": "en-US",
"name": "",
"audioTrackType": "unknown",
"isCC": false,
"isLarge": false,
"isEasyReader": false,
"isDraft": false,
"isAutoSynced": false,
"status": "serving"
}
}
]
}
And then pick the transcript you want:
https://www.googleapis.com/youtube/v3/captions/id?id=TqXDnlamg84o4bX0q2oaHz4nfWZdyiZMOrcuWsSLyPc=
or
https://www.googleapis.com/youtube/v3/captions/TqXDnlamg84o4bX0q2oaHz4nfWZdyiZMOrcuWsSLyPc=
at which point you need provide an authorization key. Apparently a simple key isn't enough. Possibly because:
Quota impact: A call to this method has a quota cost of approximately 200 units.
Note the slight difference in the URLs (/caption/ versus /caption?).
All the lovely documentation is here:
https://developers.google.com/youtube/v3/docs/captions
I may be wrong, but I don't think there is yet a documented way to get the caption track via v3 of the API. If you're authenticating with oAuth2, however, your authentication will also be good for v2 of the API, so you could do a quick call to this feed:
http://gdata.youtube.com/feeds/api/videos/[VIDEOID]/captiondata/[CAPTION TRACKID]
to get the data you want. To retrieve a list of possible caption track IDs with v2 of the API, you access this feed:
https://gdata.youtube.com/feeds/api/videos/[VIDEOID]/captions
That feed request also accepts some optional parameters, including language, max-results, etc. For more details, along with a sample that shows the returned format of the caption track list, see the documentation at https://developers.google.com/youtube/2.0/developers_guide_protocol_captions#Retrieve_Caption_Set
Heres some code I wrote which grabs all the caption tracks from any youtube video without having to use the API. Just plug the video URL in the $video_url variable.
// get video id from url
$video_url = 'https://www.youtube.com/watch?v=kYX87kkyubk';
preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+(?=\?)|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $video_url, $matches);
// get video info from id
$video_id = $matches[0];
$video_info = file_get_contents('http://www.youtube.com/get_video_info?&video_id='.$video_id);
parse_str($video_info, $video_info_array);
if (isset($video_info_array['caption_tracks'])) {
$tracks = explode(',', $video_info_array['caption_tracks']);
// print info for each track (including url to track content)
foreach ($tracks as $track) {
parse_str($track, $output);
print_r($output);
}
}
Probably the best way is using Youtube API 3. I'm trying it but you need an API key + OAuth 2.0 user. A fast solution is using captionsgrabber and parsing the returned HTML data.
Use example:
https://www.captionsgrabber.com/8302/get-captions.00.php?id=UJTY7ilwSq4
// Where the id is the youtube video id

Resources