getArtist method

Future<JsonMap> getArtist(
  1. String channelId
)

Get information about an artist and their top releases (songs, albums, singles, videos, and related artists).

The top lists contain pointers for getting the full list of releases.

Possible content types for getArtist are:

  • songs
  • albums
  • singles
  • shows
  • videos
  • episodes
  • podcasts
  • related

Each of these content keys in the response contains results and possibly browseId and params:

Arguments:

  • channelId channel id of the artist.

Returns Map with requested information.

WARNING:

  • The returned channelId is not the same as the one passed to the function. It should be used only with subscribeArtist. // TODO subscribeArtist is currently missing

Example:

{
  "description": "Oasis were ...",
  "views": "3,693,390,359 views",
  "name": "Oasis",
  "channelId": "UCUDVBtnOQi4c7E8jebpjc9Q",
  "shuffleId": "RDAOkjHYJjL1a3xspEyVkhHAsg",
  "radioId": "RDEMkjHYJjL1a3xspEyVkhHAsg",
  "subscribers": "3.86M",
  "subscribed": false,
  "thumbnails": [...],
  "songs": {
    "browseId": "VLPLMpM3Z0118S42R1npOhcjoakLIv1aqnS1",
    "results": [
      {
        "videoId": "ZrOKjDZOtkA",
        "title": "Wonderwall (Remastered)",
        "thumbnails": [...],
        "artist": "Oasis",
        "album": "(What's The Story) Morning Glory? (Remastered)"
      }
    ]
  },
  "albums": {
    "results": [
      {
        "title": "Familiar To Millions",
        "thumbnails": [...],
        "year": "2018",
        "browseId": "MPREb_AYetWMZunqA"
      }
    ],
    "browseId": "UCmMUZbaYdNH0bEd1PAlAqsA",
    "params": "6gPTAUNwc0JDbndLYlFBQV..."
  },
  "singles": {
    "results": [
      {
        "title": "Stand By Me (Mustique Demo)",
        "thumbnails": [...],
        "year": "2016",
        "browseId": "MPREb_7MPKLhibN5G"
      }
    ],
    "browseId": "UCmMUZbaYdNH0bEd1PAlAqsA",
    "params": "6gPTAUNwc0JDbndLYlFBQV..."
  },
  "videos": {
    "results": [
      {
        "title": "Wonderwall",
        "thumbnails": [...],
        "views": "358M",
        "videoId": "bx1Bh8ZvH84",
        "playlistId": "PLMpM3Z0118S5xuNckw1HUcj1D021AnMEB"
      }
    ],
    "browseId": "VLPLMpM3Z0118S5xuNckw1HUcj1D021AnMEB"
  },
  "related": {
    "results": [
      {
        "browseId": "UCt2KxZpY5D__kapeQ8cauQw",
        "subscribers": "450K",
        "title": "The Verve"
      },
      {
        "browseId": "UCwK2Grm574W1u-sBzLikldQ",
        "subscribers": "341K",
        "title": "Liam Gallagher"
      },
      ...
    ]
  }
}

Implementation

Future<JsonMap> getArtist(String channelId) async {
  final String cleanChannelId;
  if (channelId.startsWith('MPLA')) {
    cleanChannelId = channelId.substring(4);
  } else {
    cleanChannelId = channelId;
  }
  const endpoint = 'browse';
  final body = JsonMap.from({'browseId': cleanChannelId});
  final response = await sendRequest(endpoint, body);

  final results = List<JsonMap>.from(
    nav(response, [...SINGLE_COLUMN_TAB, ...SECTION_LIST]) as List,
  );

  final header =
      JsonMap.from(
            response['header']! as JsonMap,
          )['musicImmersiveHeaderRenderer']
          as JsonMap;
  final artist = <String, dynamic>{
    'name': nav(header, TITLE_TEXT),
    'description': null,
    'views': null,
  };

  final descriptionShelf = findObjectByKey(
    results,
    DESCRIPTION_SHELF[0] as String,
    isKey: true,
  );

  if (descriptionShelf != null) {
    artist['description'] = nav(descriptionShelf, DESCRIPTION);
    artist['views'] =
        descriptionShelf.containsKey('subheader')
            ? (((descriptionShelf['subheader']! as JsonMap)['runs']!
                    as List)[0]
                as JsonMap)['text']
            : null;
  }

  final subscriptionButton =
      (header['subscriptionButton']! as JsonMap)['subscribeButtonRenderer']
          as JsonMap;
  artist['channelId'] = subscriptionButton['channelId'];
  artist['shuffleId'] = nav(header, [
    'playButton',
    'buttonRenderer',
    ...NAVIGATION_PLAYLIST_ID,
  ], nullIfAbsent: true);
  artist['radioId'] = nav(header, [
    'startRadioButton',
    'buttonRenderer',
    ...NAVIGATION_PLAYLIST_ID,
  ], nullIfAbsent: true);
  artist['subscribers'] = nav(subscriptionButton, [
    'subscriberCountText',
    'runs',
    0,
    'text',
  ], nullIfAbsent: true);
  artist['subscribed'] = subscriptionButton['subscribed'];
  artist['thumbnails'] = nav(header, THUMBNAILS, nullIfAbsent: true);
  artist['songs'] = JsonMap.from({'browseId': null});

  if (results.isNotEmpty && results[0].containsKey('musicShelfRenderer')) {
    // API sometimes does not return songs
    final musicShelf = nav(results[0], MUSIC_SHELF) as JsonMap;
    if ((nav(musicShelf, TITLE) as JsonMap).containsKey(
      'navigationEndpoint',
    )) {
      (artist['songs'] as JsonMap)['browseId'] = nav(
        musicShelf,
        TITLE + NAVIGATION_BROWSE_ID,
      );
    }
    (artist['songs'] as JsonMap)['results'] = parsePlaylistItems(
      List<JsonMap>.from(musicShelf['contents'] as List),
    );
  }

  artist.addAll(parser.parseChannelContents(results));
  return artist;
}