getSongCredits method

Future<JsonMap> getSongCredits(
  1. String browseId
)

Get credits for a song. Top-level entries are limited to performed_by, written_by, produced_by and music_metadata_provided_by. If YouTube returns additional data, it will be returned in other_sections.

  • browseId browseId for the credits of a song, for example returned as creditsBrowseId in the tracks of getAlbum Returns a Map with credit sections.

Example::

{ "performed_by": { "localized_title": "Performed by", "data": "Eminem", "Beyoncé" }, "written_by": { "localized_title": "Written by", "data": "Marshall Mathers", "Beyoncé Knowles", "Holly Hafermann" }, "produced_by": { "localized_title": "Produced by", "data": "Rick Rubin" }, "music_metadata_provided_by": { "localized_title": "Music metadata provided by" "data": "Eminem Catalog PS" }, "other_sections": [ { "localized_title": "Piano", "data": "Skylar Grey" } ] }

Implementation

Future<JsonMap> getSongCredits(String browseId) async {
  if (browseId.isEmpty || !browseId.startsWith('MPTC')) {
    throw Exception(
      'Invalid song credits browseId provided, must start with MPTC.',
    );
  }
  final body = {'browseId': browseId};
  const endpoint = 'browse';
  final response = await sendRequest(endpoint, body);

  final credits = <String, dynamic>{'other_sections': []};
  final sections = List<JsonMap>.from(
    nav(response, CREDITS_SECTIONS) as List,
  );
  final localizedSectionMap = parser.getSongCreditSectionMap();
  for (final section in sections) {
    final sectionContent = section['dismissableDialogContentSectionRenderer'];
    final sectionLocalName = nav(sectionContent, TITLE_TEXT);
    final sectionSnakeCaseName =
        localizedSectionMap[sectionLocalName] as String?;
    final subtitleRuns = List<JsonMap>.from(
      nav(sectionContent, SUBTITLE_RUNS) as List? ?? [],
    );

    final sectionData = {
      'localized_title': sectionLocalName,
      'data': [
        for (var i = 0; i < subtitleRuns.length; i += 2)
          subtitleRuns[i]['text'],
      ],
    };

    if (sectionSnakeCaseName != null) {
      credits[sectionSnakeCaseName] = sectionData;
    } else {
      (credits['other_sections'] as List).add(sectionData);
    }
  }
  return credits;
}