gmusicapi
gmusicapi copied to clipboard
Mobileclient v2.1 - New Releases
New API-Url https://mclients.googleapis.com/sj/v2.1/
Listen now content can be retrieved via:
sj_url + explore/tabs (supports dynamic_param -> num_items and genre)
Original response (stripped-down) (genre=DANCE_ELECTRONIC)
{
"tabs": [
{
"tab_type": "TOP_CHARTS",
"kind": "sj#exTab",
"groups": [
{
"kind": "sj#exEntityGroup",
"title": "Featured Playlists",
"entities": [
{
"kind": "sj#exEntity",
"playlist": {
"shareToken": "AMaBXynOOlKNTexP54IxHI8nLhyiM1u26umr-4LSeI1PdCOVTUGKPtvCjrUoFRXLqMKg2kDKJqSBz03G7jzzm5m5qBSCtEoE5Q==",
"name": "Dubstep Workout",
"albumArtRef": [
{
"url": "http://lh6.ggpht.com/..."
}
],
"kind": "sj#playlist",
"ownerName": "Alex Moog",
"type": "SHARED",
"description": ""
}
}
],
"start_position": 0,
"continuation_token": "Q2hGR1JVRlVWVkpGUkY5UVRFRlpURWxUVkJJQ1JFVVNFRVJCVGtORlgwVk1SVU5VVWs5T1NVTT0=",
"group_type": "TOP_PLAYLISTS"
},
{
"kind": "sj#exEntityGroup",
"title": "Top Albums",
"entities": [
{
"album": {
"kind": "sj#album",
"name": "Stories",
"artist": "Avicii",
"albumArtRef": "http://lh3.googleusercontent.com/...",
"albumId": "Boxhbhme3x6znuljqbo5igh4enq",
"artistId": [
"Atrxtalf4tqdl5f2tdq4zv7oriy"
],
"albumArtist": "Avicii",
"year": 2015
},
"kind": "sj#exEntity"
}
],
"start_position": 0,
"continuation_token": "Q2hWMGIzQnpaV3hzYVc1blgzQmhhV1JmWVd4aWRXMFNFRVJCVGtORlgwVk1SVU5VVWs5T1NVTT0=",
"group_type": "TOP_ALBUMS"
},
{
"kind": "sj#exEntityGroup",
"title": "Key Albums",
"entities": [
{
"album": {
"kind": "sj#album",
"description_attribution": {
"kind": "sj#attribution",
"source_title": "-- Vivian Host, Google Play"
},
"name": "18 Months",
"artist": "Calvin Harris",
"albumArtRef": "http://lh4.ggpht.com/...",
"albumId": "Btojjftsw2glbk7rwrphfz6wuba",
"artistId": [
"Avwbbklu2vufocv7d7ccglejzq4"
],
"albumArtist": "Calvin Harris",
"year": 2012
},
"kind": "sj#exEntity"
}
],
"start_position": 0,
"continuation_token": "Q2hWblpXNXlaVjlqWVc1dmJtbGpZV3hmWVd4aWRXMFNFRVJCVGtORlgwVk1SVU5VVWs5T1NVTT0=",
"group_type": "KEY_ALBUMS"
},
{
"kind": "sj#exEntityGroup",
"title": "Top Songs",
"entities": [
{
"track": {
"album": "Sugar (feat. Francesco Yates)",
"kind": "sj#track",
"storeId": "Tpzyo6lgdmo7l4dvy3avwu5tu44",
"contentType": "2",
"artist": "Robin Schulz",
"albumArtRef": [
{
"url": "http://lh3.googleusercontent.com/...",
"kind": "sj#imageRef",
"aspectRatio": "1",
"autogen": false
}
],
"title": "Sugar (feat. Francesco Yates)",
"nid": "Tpzyo6lgdmo7l4dvy3avwu5tu44",
"estimatedSize": "8764631",
"albumId": "Bvhrgwo6czsm56kxnfc2avq2chy",
"artistId": [
"Astdnwf3jliwvd2yyzseaqvhzwi",
"Agg7kd5wfqjwyfihmazcftsfrvu"
],
"albumArtist": "Robin Schulz",
"durationMillis": "219000",
"composer": "",
"trackAvailableForSubscription": true,
"genre": "Dance/Electronic",
"trackNumber": 1,
"discNumber": 1,
"trackAvailableForPurchase": true,
"trackType": "7",
"albumAvailableForPurchase": true
},
"kind": "sj#exEntity"
}
],
"start_position": 0,
"continuation_token": "Q2hWMGIzQnpaV3hzYVc1blgzQmhhV1JmZEhKaFkyc1NFRVJCVGtORlgwVk1SVU5VVWs5T1NVTT0=",
"group_type": "TOP_SONGS"
}
]
},
{
"tab_type": "NEW_RELEASES",
"kind": "sj#exTab",
"groups": [
{
"kind": "sj#exEntityGroup",
"title": "New Releases",
"entities": [
{
"album": {
"kind": "sj#album",
"name": "Stories",
"artist": "Avicii",
"albumArtRef": "http://lh3.googleusercontent.com/...",
"albumId": "Boxhbhme3x6znuljqbo5igh4enq",
"artistId": [
"Atrxtalf4tqdl5f2tdq4zv7oriy"
],
"albumArtist": "Avicii",
"year": 2015
},
"kind": "sj#exEntity"
}
],
"start_position": 0,
"continuation_token": "Q2c1dGIzWmxjbk5mYzJoaGEyVnljeElRUkVGT1EwVmZSVXhGUTFSU1QwNUpRdz09",
"group_type": "NEW_RELEASE"
}
]
}
],
"kind": "sj#exGetTabsResponse"
}
Proof-of-Concept implementation
#protocol/mobileclient.py
class GetNewReleases(McCall):
static_params = {'alt': 'json'}
static_method = 'GET'
static_url = sj_url + 'explore/tabs'
@staticmethod
def dynamic_params(num_items, genre):
params = {'num-items': num_items}
if genre is not None:
params['genre'] = genre
return params
#clients/mobileclient.py
...
# Not quite sure yet.
# "tab_type" and "group_type" might sute to filter the response.
# But we don't know either of them before a initial request.
...
Thanks for putting these together!