I am using YouTube Data's Search API v3 to fetch videos. I am able to fetch videos properly with the below mentioned HTTPS GET request. But this API is listing paid videos too, like the one having the ID FKUvkKsTzV8. That I would like to skip from fetching.
I have gone through the Search API documentation, but was unable to identify the filter for fetching only free videos -- not paid videos.
Please suggest me the filter to fetch only free videos from Search API, if any.
Here is the URL of my HTTPS GET request:
https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=5&q=frozen&key=[My api key]&type=video&order=relevance
Edited with more information:
The given video is an example, which will play in some regions only. So adding some more similar to the above mentioned video. I would like to skip these kind of videos from my search result.
https://www.youtube.com/watch?v=ZMWjixQbqXY
https://www.youtube.com/watch?v=Zat88Rsxp94
https://www.youtube.com/watch?v=2YQ9W0BP2Gw
The videos which are free to play is given below
https://www.youtube.com/watch?v=7TavVZMewpY
Looking into the Videos resource meta-data attached to the videos of which ID you mentioned within your question, I deduce that your issue may be reformulated as follows:
Do use the Search.list API endpoint for to search for videos -- using the parameter q as needed --, but exclude from the result set that's provided by the endpoint those videos that are not allowed to be viewed in certain (given) regions.
The Videos resource attached to each video does contain the info that specifies that particular condition above, namely the properties:
contentDetails.regionRestriction (object)
The regionRestriction object contains information about the countries where a video is (or is not) viewable. The object will contain either the contentDetails.regionRestriction.allowed property or the contentDetails.regionRestriction.blocked property.
contentDetails.regionRestriction.allowed[] (list)
A list of region codes that identify countries where the video is viewable. If this property is present and a country is not listed in its value, then the video is blocked from appearing in that country. If this property is present and contains an empty list, the video is blocked in all countries.
contentDetails.regionRestriction.blocked[] (list)
A list of region codes that identify countries where the video is blocked. If this property is present and a country is not listed in its value, then the video is viewable in that country. If this property is present and contains an empty list, the video is viewable in all countries.
Unfortunately, one cannot specify explicitly to the Search.list endpoint a filter based on these properties.
Nevertheless, you may retain as much IDs as you can from Search.list and then query the Videos.list API endpoint for precisely these properties with the purpose of filtering out programatically the videos that are not viewable in the regions of your interest.
The URL that will invoke the Videos.list endpoint would look like:
https://www.googleapis.com/youtube/v3/videos?key=$APP_KEY&id=$VIDEO_IDS&part=contentDetails,id&fields=items(id,contentDetails(regionRestriction))&maxResults=$VIDEO_COUNT
where $APP_KEY is your API key, $VIDEO_IDS is a comma-separated list of video IDs and $VIDEO_COUNT is the number of video IDs that $VIDEO_IDS contains. (Note that $VIDEO_COUNT should not exceed 50.)
Note that the URL above is using the parameter fields for to obtain from the endpoint only the properties that are of actual use. (It's always good to ask from the API only the info that is really needed.)
When setting $VIDEO_COUNT to 5 and $VIDEO_IDS to
FKUvkKsTzV8,ZMWjixQbqXY,Zat88Rsxp94,2YQ9W0BP2Gw,7TavVZMewpY
within the URL above, Videos.list returns the following JSON text:
{
"items": [
{
"id": "FKUvkKsTzV8",
"contentDetails": {
"regionRestriction": {
"allowed": [
"BE",
"NL"
]
}
}
},
{
"id": "ZMWjixQbqXY",
"contentDetails": {
"regionRestriction": {
"allowed": [
"NL"
]
}
}
},
{
"id": "Zat88Rsxp94",
"contentDetails": {
"regionRestriction": {
"allowed": [
"BE",
"NL"
]
}
}
},
{
"id": "2YQ9W0BP2Gw",
"contentDetails": {
"regionRestriction": {
"allowed": [
"PE",
"KG",
"PA",
"PL",
"PH",
"TZ",
"TW",
"TH",
"TJ",
"TM",
"PY",
"KZ",
"GR",
"CY",
"GT",
"CZ",
"CV",
"CR",
"GA",
"CL",
"CO",
"CI",
"SN",
"SI",
"SK",
"SE",
"NP",
"KH",
"NI",
"ID",
"NO",
"NL",
"NA",
"NE",
"PT",
"BZ",
"BY",
"BW",
"BO",
"BJ",
"BF",
"BE",
"ZW",
"MU",
"MT",
"VE",
"EE",
"EC",
"IS",
"MD",
"RW",
"ML",
"AZ",
"ZM",
"LV",
"AR",
"AO",
"AM",
"TG",
"SG",
"DK",
"LT",
"UZ",
"UY",
"DO",
"HU",
"LA",
"HN",
"UG",
"LK",
"UA",
"FI",
"SV"
]
}
}
},
{
"id": "7TavVZMewpY",
"contentDetails": {}
}
]
}
This response indicates that the video identified by FKUvkKsTzV8 is viewable only in NL and BE regions, while the video identified by 7TavVZMewpY has no region restrictions at all (i.e. is freely-viewable everywhere).
Now, it's quite simple to access the properties under the object items[].contantDetails.regionRestriction for to exclude from a filtered result set those video IDs that are not viewable within the regions of your interest.
Addendum
Not sure that what follows will help, but nevertheless, I'll have to mention that the Search.list endpoint does have the following parameter:
regionCode (string)
The regionCode parameter instructs the API to return search results for videos that can be viewed in the specified country. The parameter value is an ISO 3166-1 alpha-2 country code.
The above official specification does not indicate whether regionCode allows one to specify a set of regions, or, otherwise, how to specify to regionCode the set of all regions.
Related
I am doing a very simple search using iTunes api to try to retrieve a list of podcast of a certain user, the result only shows 1 but the track list is 25. Is there any way to view all “tracks”?
I was able to reproduce the following result using the URL in your comment below:
{
"resultCount": 1,
"results": [
{
"wrapperType": "track",
"kind": "podcast",
"collectionId": 1157898727,
"trackId": 1157898727,
"artistName": "Phoenix FM",
"collectionName": "The West Ham Way on Phoenix FM",
"trackName": "The West Ham Way on Phoenix FM",
"collectionCensoredName": "The West Ham Way on Phoenix FM",
"trackCensoredName": "The West Ham Way on Phoenix FM",
"collectionViewUrl": "https://itunes.apple.com/us/podcast/the-west-ham-way-on-phoenix-fm/id1157898727?mt=2&uo=4",
"feedUrl": "http://feeds.feedburner.com/TheWestHamWayOnPhoenixFm",
"trackViewUrl": "https://itunes.apple.com/us/podcast/the-west-ham-way-on-phoenix-fm/id1157898727?mt=2&uo=4",
"artworkUrl30": "https://is1-ssl.mzstatic.com/image/thumb/Music42/v4/b1/c0/76/b1c076ed-e555-af3b-3f09-5dfc379da0cb/source/30x30bb.jpg",
"artworkUrl60": "https://is1-ssl.mzstatic.com/image/thumb/Music42/v4/b1/c0/76/b1c076ed-e555-af3b-3f09-5dfc379da0cb/source/60x60bb.jpg",
"artworkUrl100": "https://is1-ssl.mzstatic.com/image/thumb/Music42/v4/b1/c0/76/b1c076ed-e555-af3b-3f09-5dfc379da0cb/source/100x100bb.jpg",
"collectionPrice": 0,
"trackPrice": 0,
"trackRentalPrice": 0,
"collectionHdPrice": 0,
"trackHdPrice": 0,
"trackHdRentalPrice": 0,
"releaseDate": "2019-01-23T22:03:00Z",
"collectionExplicitness": "cleaned",
"trackExplicitness": "cleaned",
"trackCount": 25,
"country": "USA",
"currency": "USD",
"primaryGenreName": "Professional",
"contentAdvisoryRating": "Clean",
"artworkUrl600": "https://is1-ssl.mzstatic.com/image/thumb/Music42/v4/b1/c0/76/b1c076ed-e555-af3b-3f09-5dfc379da0cb/source/600x600bb.jpg",
"genreIds": [
"1465",
"26",
"1316"
],
"genres": [
"Professional",
"Podcasts",
"Sports & Recreation"
]
}
]
}
According to this answer by juhariis, you'll need to hit the feedURL (in this case, "http://feeds.feedburner.com/TheWestHamWayOnPhoenixFm") in the result to get access to the actual episodes.
There are probably language or framework-specific packages you to help you out with this.
I hope this helps!
Old Answer
Are you sure your search URL doesn't look like this: https://itunes.apple.com/search?term=firstname+lastname&limit=1?
According to the iTunes Web Service Search API documentation, the limit parameter isn't required in the request URL, so you can simply remove the "&limit=1" part of the query string:
To search for all Jack Johnson audio and video content (movies, podcasts, music, music videos, audiobooks, short films, and tv shows), your URL would look like the following:
https://itunes.apple.com/search?term=jack+johnson
Is there any way of getting a list of albums for an artist (band), along with a link to album art and runtime?
I've been given this endpoint, but the data it returns is confusing:
http://musicbrainz.org/ws/2/recording?query=artist:%22Queen%22%20and%20type:album&fmt=json
The data isn't really organized around albums, and the "length" data returns something like 203000. But it's better if you see it in context, so here's the first bit of it (sorry I couldn't get it indented):
{
"created": "2018-02-17T03:47:57.052Z",
"count": 9533710,
"offset": 0,
"recordings": [
{
"id": "c2e919f7-ecb9-4fdf-9162-3c26d0127fa0",
"score": "100",
"title": "Son and Daughter",
"length": 203000,
"video": null,
"artist-credit": [
{
"artist": {
"id": "0383dadf-2a4e-4d10-a46a-e9e041da8eb3",
"name": "Queen",
"sort-name": "Queen",
"disambiguation": "UK rock group",
"aliases": [
{
"sort-name": "Queen + Adam Lambert",
"name": "Queen + Adam Lambert",
"locale": null,
"type": null,
"primary": null,
"begin-date": "2011",
"end-date": null
}
]
}
}
],
"releases": [
{
"id": "bb19abaf-80b3-4a3e-846d-5f12b12af827",
"title": "Queen",
"status": "Official",
"release-group": {
"id": "810068af-2b3c-3e9c-b2ab-68a3f3e3787d",
"primary-type": "Album"
},
"date": "1994",
"country": "NL",
"release-events": [
{
"date": "1994",
"area": {
"id": "ef1b7cc0-cd26-36f4-8ea0-04d9623786c7",
"name": "Netherlands",
"sort-name": "Netherlands",
"iso-3166-1-codes": [
"NL"
]
}
}
],
"track-count": 10,
"media": [
{
"position": 1,
"format": "CD",
"track": [
{
"id": "3a26455e-2660-30dc-a652-6a2b40f1fbe5",
"number": "8",
"title": "Son and Daughter",
"length": 203400
}
],
"track-count": 10,
"track-offset": 7
}
]
},
{
"id": "1783da6a-9315-3602-a488-1738eb733a0f",
"title": "Queen",
"status": "Official",
"release-group": {
"id": "810068af-2b3c-3e9c-b2ab-68a3f3e3787d",
"primary-type": "Album"
},
"date": "1973-09-04",
"country": "US",
"release-events": [
{
"date": "1973-09-04",
"area": {
"id": "489ce91b-6658-3307-9877-795b68554c98",
"name": "United States",
"sort-name": "United States",
"iso-3166-1-codes": [
"US"
]
}
}
],
If someone can explain this data to me, then I don't need another endpoint. But I've been hunting around the musicbrainz docs and they're not super helpful.
Preferably it would be with one call, but I can do successive calls if necessary.
Thanks for your help.
First off:
Is there any way of getting a list of albums for an artist (band), along with a link to album art and runtime?
Yes, definitely.
First you will want to find the artist, say, the Queen that did Bohemian Rhapsody. They're identified with MusicBrainz Artist ID "0383dadf-2a4e-4d10-a46a-e9e041da8eb3", so you can do a browse request for Releases by this artist: https://musicbrainz.org/ws/2/release/?artist=0383dadf-2a4e-4d10-a46a-e9e041da8eb3&inc=recordings&fmt=json (note the inc=recordings)
This gives you most of what you are asking for. A list of releases and their runtime—kind of. Each Release should have one or more medium properties that in turn have a track-list with a number of tracks. The sum of the length of each of these tracks is what makes up the runtime (the length is given in milliseconds).
For cover art, you may notice that the output has a cover-art-archive property. For cover art, MusicBrainz uses Cover Art Archive which uses MusicBrainz IDs as identifiers. The cover-art-archive attribute states whether any cover art exists in Cover Art Archive and a few details about this—e.g., does CAA have any images at all (artwork)? Does it have a back image (back) and/or a front image (front)? How many images are there in all for the release (count)? If the cover-art-archive→artwork is true, we can go on and fetch cover art from the CAA. The CAA's API is really simple: to get the "front" image of a release, say the 1974 UK single "Killer Queen" that has MusicBrainz Release ID "a2d12ee8-9aeb-4d91-bfab-5c21f7a577fc", you can simply do https://coverartarchive.org/release/a2d12ee8-9aeb-4d91-bfab-5c21f7a577fc/front
You can also do https://coverartarchive.org/release/a2d12ee8-9aeb-4d91-bfab-5c21f7a577fc to get a JSON document with more details about what cover art images are available (e.g., this one has two images: one Front+Medium and one Back+Medium image).
The Cover Art Archive API is documented at https://musicbrainz.org/doc/Cover_Art_Archive/API and the MusicBrainz API/web service documentation can be found at https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2
Note that using browse requests you can page through the results using offset and vary the amount of results per query using limit, see the "Paging" section under the browse request section in the MusicBrainz WS documentation.
Secondly: Though you don't ask about this directly, you're using a search query using a generic term in your question, so I thought I'd talk about this for a bit. In MusicBrainz everything is identified using MusicBrainz identifiers (IDs). (I kind of mentioned them in the first section too.)
The reason for this is that many, many names are not unique. There are as of this writing three unique artists known as "Queen" in MusicBrainz: https://musicbrainz.org/search?query=%22queen%22&type=artist&method=advanced – not counting any of the 321 other artists that have "queen" as part of their name. Without more information, it is not possible for MusicBrainz to know which of them you want to find out information from, so your first step will likely be to somehow either narrow the search (e.g., add type:group narrows the search to 123 results, using country:gb limits to 21 results, doing both gives 11 results (see the search syntax documentation for more details)) or somehow filter afterwards.
Once you've narrowed it down to the specific artist you want, you can continue with the steps outlined above to get the details you want. The steps for narrowing it down will depend on your specific application/use case.
Finally: You seem to have some missing understanding at the asbstract level about how MusicBrainz's data is structured. E.g., all of the above is assuming that by album you mean a specific released version like the 1974 UK "Killer Queen" single, and not a more generic concept of a release like any version of the "Killer Queen" single, which in MusicBrainz terminology would be a Release Group.
https://musicbrainz.org/doc/MusicBrainz_Entity is a list of entities used in MusicBrainz. Understanding the differences between a Release Group and a Release as well as between Tracks and Recordings (and Works) will put you in a much better position to effectively use the web service and the MusicBrainz data in general.
https://musicbrainz.org/doc/MusicBrainz_Database/Schema is a introduction to how MusicBrainz is structured. Knowing how artist credits, ("advanced") relationships, and mediums play into things is also likely to save you a lot of headache later.
You need to understand the format of the data returned, copy the result in to a JSON formatting service such as https://jsonformatter.curiousconcept.com/
You will then realise you have multiple artists in the returned data, which is why it's not as simple as "albums by artist"
I’m guessing the "length" data is in milliseconds.
I have a question regarding the trends/place REST API of Twitter.
This API, according to Twitter "returns the top 50 trending topic for a specific WOEID, if trending information is available for it."
Thus it returns a list of trend topic dictionaries with the topic in the name field, all in json format
One of the fields returned in the response is the tweet_volume. My question is whether the tweet_volume represents the volume just for that WOEID, or whether this is the tweet volume across all of Twitter.
Here is a sample:
[
{
"created_at": "2015-12-23T10:26:00Z",
"trends": [
{
"url": "http://twitter.com/search?q=%22Mesut+Ozil%22",
"query": "%22Mesut+Ozil%22",
"tweet_volume": 17195,
"name": "Mesut Ozil",
"promoted_content": null
},
"locations": [
{
"woeid": 23424863,
"name": "Kenya"
}
]
}
]
The tweet_volume value is brand new addition to the API. You can learn about it on the Twitter Developer forums:
Additionally, we are also now returning a tweet_volume for each trend
- this is the volume of tweets per trend for the last 24 hours.
I believe that this is across the site rather than per WOEID but ICBW.
I need to get the highway name on which the user is currently navigating.
That can be done in navigation mode, getting it from
-(void)routingService:(SKRoutingService *)routingService didChangeCurrentStreetName:(NSString *)currentStreetName streetType:(SKStreetType)streetType countryCode:(NSString *)countryCode
So, when I was testing my app yesterday, I was on the highway, and yes, Skobbler did recognised that I am on one, and yes, I got the Highway name back.
It was "Brooklyn-Queens Expressway".
But, Brooklyn-Queens Expressway is actually name of the I-278 Interstate highway, and all the functions I would later have to use, need to get Highway name in that format I-nnn
Here is the map photo of what I mean
So, Is there a way to get streetName in that I-nnn format, when the streetType is recognised as an interstate highway?
Or is there any Open Streetmap database we could consult? I wasn't able to find anything on OSM Wiki.
Don't know about the Skobbler SDK, but if online query is available and you have the approximate geographical area and the name of the motorway, you may use the Overpass API (http://wiki.openstreetmap.org/wiki/Overpass_API) to query the openstreetmap database for the highway reference.
For example, the following query (for a particular bbox which contains a small section of the highway):
[out:json]
[timeout:25]
;
(
way
["highway"="motorway"]
["name"="Brooklyn-Queens Expressway"]
(40.73483602685421,-73.91463160514832,40.73785205632046,-73.9096748828888);
);
out body qt;
returns (with some key-value pairs omitted for simplicity):
{
"version": 0.6,
"generator": "Overpass API",
"osm3s": {
"timestamp_osm_base": "2015-09-18T20:21:02Z",
"copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."
},
"elements": [
{
"type": "way",
"id": 46723482,
"nodes": [
488264429,
488264444,
488264461,
488264512,
488264530,
488264541,
597315979
],
"tags": {
"bicycle": "no",
"bridge": "yes",
"foot": "no",
"hgv": "designated",
"highway": "motorway",
"horse": "no",
"lanes": "3",
"layer": "1",
"name": "Brooklyn-Queens Expressway",
"oneway": "yes",
"ref": "I 278",
"sidewalk": "none",
}
},
{
"type": "way",
"id": 46724225,
"nodes": [
597315978,
488242888,
488248526,
488248544,
488248607
],
"tags": {
"bicycle": "no",
"bridge": "yes",
"foot": "no",
"hgv": "designated",
"highway": "motorway",
"horse": "no",
"lanes": "3",
"layer": "1",
"name": "Brooklyn-Queens Expressway",
"oneway": "yes",
"ref": "I 278",
"sidewalk": "none",
}
}
]
}
Which are 2 sections of the road in the osm database. In the US the "ref" tag for interstates is in the form "I XXX" (See http://wiki.openstreetmap.org/wiki/Interstate_Highways and note the format for co-location). You can retrieve the interstate name accordingly.
You can try the above query in overpass-turbo (a UI for the service) at http://overpass-turbo.eu/s/bxi (Press RUN and the DATA tab for the returned data, and pan the map for query in another bbox).
The "ref" information is not exposed in the SDK (will put this on the TODO list).
A workaround would be to look in the text advices (when using TTS) as this information is there (if you look at the $ref parameter, that contains the information you are looking for).
For more details regarding the text advices structure, see this blog article.
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