Beispiel #1
0
    def test_list_composer_should_not_return_artists_without_names(self):
        self.backend.library.dummy_find_exact_result = SearchResult(
            tracks=[Track(composers=[Artist(name='')])])

        self.send_request('list "composer"')
        self.assertNotInResponse('Artist: ')
        self.assertNotInResponse('Albumartist: ')
        self.assertNotInResponse('Composer: ')
        self.assertNotInResponse('Performer: ')
        self.assertInResponse('OK')
Beispiel #2
0
    def _convert_album(self, album):
        """
        Transforms a beets album into a mopidy Track
        """
        if not album:
            return
        album_kwargs = {}
        artist_kwargs = {}

        if 'album' in album:
            album_kwargs['name'] = album['album']

        if 'disctotal' in album:
            album_kwargs['num_discs'] = album['disctotal']

        if 'tracktotal' in album:
            album_kwargs['num_tracks'] = album['tracktotal']

        if 'mb_albumid' in album:
            album_kwargs['musicbrainz_id'] = album['mb_albumid']

        album_kwargs['date'] = None
        if self.backend.use_original_release_date:
            if 'original_year' in album:
                album_kwargs['date'] = self._build_date(
                    album['original_year'], album['original_month'],
                    album['original_day'])
        else:
            if 'year' in album:
                album_kwargs['date'] = self._build_date(
                    album['year'], album['month'], album['day'])

        # if 'added' in item:
        #    album_kwargs['last_modified'] = album['added']

        # if 'artpath' in album:
        #    album_kwargs['images'] = [album['artpath']]

        if 'albumartist' in album:
            artist_kwargs['name'] = album['albumartist']

        if 'mb_albumartistid' in album:
            artist_kwargs['musicbrainz_id'] = album['mb_albumartistid']

        if artist_kwargs:
            artist = Artist(**artist_kwargs)
            album_kwargs['artists'] = [artist]

        if 'id' in album:
            album_kwargs['uri'] = uricompose('beetslocal', None,
                                             'album:%s:' % album['id'])

        album = Album(**album_kwargs)
        return album
Beispiel #3
0
 def test_serialize_with_artists(self):
     artist = Artist(name="foo")
     self.assertDictEqual(
         {
             "__model__": "Track",
             "uri": "uri",
             "name": "name",
             "artists": [artist.serialize()],
         },
         Track(uri="uri", name="name", artists=[artist]).serialize(),
     )
    def test_list_albumartist_should_not_return_artists_without_names(self):
        self.backend.library.dummy_find_exact_result = SearchResult(
            tracks=[Track(album=Album(artists=[Artist(name="")]))]
        )

        self.send_request('list "albumartist"')
        self.assertNotInResponse("Artist: ")
        self.assertNotInResponse("Albumartist: ")
        self.assertNotInResponse("Composer: ")
        self.assertNotInResponse("Performer: ")
        self.assertInResponse("OK")
Beispiel #5
0
def to_mopidy_album(track):
    if track is None:
        return
    artist = track['albumArtist']
    if artist.strip() == '':
        artist = track['artist']
    return Album(name=track['album'],
                 artists=[Artist(name=artist)],
                 num_tracks=track.get('totalTracks', 1),
                 num_discs=track.get('totalDiscs', track.get('disc', 1)),
                 date=track.get('year', 1970))
Beispiel #6
0
 def raw_album_to_album(self, album):
     if album is None:
         return None
     return Album(name=album.get('title') or album.get('name')
                  or UNKNOWN_ALBUM,
                  num_tracks=album.get('songCount'),
                  uri=uri.get_album_uri(album.get('id')),
                  artists=[
                      Artist(name=album.get('artist'),
                             uri=uri.get_artist_uri(album.get('artistId')))
                  ])
Beispiel #7
0
    def test_unicode_cache(self):
        tracks = parse_mpd_tag_cache(
            path_to_data_dir('utf8_tag_cache'), path_to_data_dir(''))

        artists = [Artist(name='æøå')]
        album = Album(name='æøå', artists=artists)
        track = Track(
            uri='local:track:song1.mp3', name='æøå', artists=artists,
            album=album, length=4000, last_modified=1272319626)

        self.assertEqual(track, list(tracks)[0])
Beispiel #8
0
    def test_unicode_cache(self):
        tracks = parse_mpd_tag_cache(
            path_to_data_dir('utf8_tag_cache'), path_to_data_dir(''))

        uri = path_to_uri(path_to_data_dir('song1.mp3'))
        artists = [Artist(name='æøå')]
        album = Album(name='æøå', artists=artists)
        track = Track(
            uri=uri, name='æøå', artists=artists, album=album, length=4000)

        self.assertEqual(track, list(tracks)[0])
Beispiel #9
0
def uploadArtistToTracks(artist):
    for track in artist:
        TRACKS[track["videoId"]] = Track(
            uri=f"ytm:video?id={track['videoId']}",
            name=track["title"],
            artists=[
                Artist(
                    uri=f"ytm:artist?id={a['id']}&upload=true",
                    name=a["name"],
                    sortname=a["name"],
                    musicbrainz_id="",
                ) for a in track["artist"]
            ],
            album=Album(
                uri=f"ytm:album?id={track['album']['id']}&upload=true",
                name=track["album"]["name"],
                artists=[
                    Artist(
                        uri=f"ytm:artist?id={a['id']}&upload=true",
                        name=a["name"],
                        sortname=a["name"],
                        musicbrainz_id="",
                    ) for a in track["artist"]
                ],
                num_tracks=None,
                num_discs=None,
                date="1999",
                musicbrainz_id="",
            ),
            composers=[],
            performers=[],
            genre="",
            track_no=None,
            disc_no=None,
            date="1999",
            length=None,
            bitrate=0,
            comment="",
            musicbrainz_id="",
            last_modified=None,
        )
Beispiel #10
0
 def test_ne(self):
     track1 = Track(uri='uri1',
                    name='name1',
                    artists=[Artist(name='name1')],
                    album=Album(name='name1'),
                    track_no=1,
                    date='1977-01-01',
                    length=100,
                    bitrate=100,
                    musicbrainz_id='id1')
     track2 = Track(uri='uri2',
                    name='name2',
                    artists=[Artist(name='name2')],
                    album=Album(name='name2'),
                    track_no=2,
                    date='1977-01-02',
                    length=200,
                    bitrate=200,
                    musicbrainz_id='id2')
     self.assertNotEqual(track1, track2)
     self.assertNotEqual(hash(track1), hash(track2))
Beispiel #11
0
def wrap_album(plexalbum, plex_uri_method, resolve_uri_method):
    '''Wrap a plex search result in mopidy.model.album'''
    return Album(uri=plex_uri_method(plexalbum.ratingKey, 'plex:album'),
                 name=plexalbum.title,
                 artists=[Artist(uri=plex_uri_method(plexalbum.parentKey, 'plex:artist'),
                                 name=plexalbum.parentTitle)],
                 num_tracks=plexalbum.leafCount,
                 num_discs=None,
                 date=str(plexalbum.year),
                 images=[resolve_uri_method(plexalbum.thumb),
                         resolve_uri_method(plexalbum.art)]
                )
Beispiel #12
0
 def test_eq(self):
     date = '1977-01-01'
     artists = [Artist()]
     album = Album()
     track1 = Track(
         uri='uri', name='name', artists=artists, album=album, track_no=1,
         date=date, length=100, bitrate=100, musicbrainz_id='id')
     track2 = Track(
         uri='uri', name='name', artists=artists, album=album, track_no=1,
         date=date, length=100, bitrate=100, musicbrainz_id='id')
     self.assertEqual(track1, track2)
     self.assertEqual(hash(track1), hash(track2))
Beispiel #13
0
 def test_ne(self):
     track1 = Track(uri=u'uri1',
                    name=u'name1',
                    artists=[Artist(name=u'name1')],
                    album=Album(name=u'name1'),
                    track_no=1,
                    date=datetime.date.today(),
                    length=100,
                    bitrate=100,
                    musicbrainz_id='id1')
     track2 = Track(uri=u'uri2',
                    name=u'name2',
                    artists=[Artist(name=u'name2')],
                    album=Album(name=u'name2'),
                    track_no=2,
                    date=datetime.date.today() - datetime.timedelta(days=1),
                    length=200,
                    bitrate=200,
                    musicbrainz_id='id2')
     self.assertNotEqual(track1, track2)
     self.assertNotEqual(hash(track1), hash(track2))
Beispiel #14
0
def test_lookup_artist(r_get_mock, emby_client):
    with open('tests/data/lookup_artist0.json', 'r') as f:
        r_get_mock.return_value = json.load(f)

    assert emby_client.lookup_artist(0) == [
        Track(album=Album(artists=[Artist(name=u'Jawbreaker')],
                          name=u'24 Hour Revenge Therapy'),
              artists=[Artist(name=u'Jawbreaker')],
              length=159840,
              name=u'The Boat Dreams From The Hill',
              track_no=1,
              uri='emby:track:05321ccb30ff9e43bf8070cd5f70c783'),
        Track(album=Album(artists=[Artist(name=u'Jawbreaker')],
                          name=u'Dear You'),
              artists=[Artist(name=u'Jawbreaker')],
              length=131133,
              name=u'Bad Scene, Everyone\u2019s Fault',
              track_no=10,
              uri='emby:track:0a24ce6c243f2f3a81fa0f99625630b4'),
        Track(album=Album(artists=[Artist(name=u'Jawbreaker')],
                          name=u'Dear You'),
              artists=[Artist(name=u'Jawbreaker')],
              length=254107,
              name=u'Sluttering (May 4th)',
              track_no=11,
              uri='emby:track:057801bc10cf08ce96e1e19bf98c407f')
    ]
Beispiel #15
0
    def search(self, query=None, uris=None, exact=False):
        # TODO Support exact search
        logger.info('youtube LibraryProvider.search "%s"', query)

        # handle only searching (queries with 'any') not browsing!
        if not (query and "any" in query):
            return None

        search_query = " ".join(query["any"])
        logger.info('Searching YouTube for query "%s"', search_query)

        try:
            entries = youtube.Entry.search(search_query)
        except Exception as e:
            logger.error('search error "%s"', e)
            return None

        # load playlist info (to get video_count) of all playlists together
        playlists = [entry for entry in entries if not entry.is_video]
        youtube.Playlist.load_info(playlists)

        tracks = []
        for entry in entries:
            if entry.is_video:
                uri_base = "youtube:video"
                album = "YouTube Video"
                length = int(entry.length.get()) * 1000
            else:
                uri_base = "youtube:playlist"
                album = "YouTube Playlist (%s videos)" % entry.video_count.get()
                length = 0

            name = entry.title.get()

            tracks.append(
                Track(
                    name=name.replace(";", ""),
                    comment=entry.id,
                    length=length,
                    artists=[Artist(name=entry.channel.get())],
                    album=Album(name=album),
                    uri="%s/%s.%s" % (uri_base, safe_url(name), entry.id),
                )
            )

        # load video info and playlist videos in the background. they should be
        # ready by the time the user adds search results to the playing queue

        for pl in playlists:
            pl.videos  # start loading

        return SearchResult(uri="youtube:search", tracks=tracks)
Beispiel #16
0
def wrap_track(plextrack, plex_uri_method):
    '''Wrap a plex search result in mopidy.model.track'''
    return Track(uri=plex_uri_method(plextrack.ratingKey, 'plex:track'),
                 name=plextrack.title,
                 artists=[Artist(uri=plex_uri_method(plextrack.grandparentKey, 'plex:artist'),
                                 name=plextrack.grandparentTitle)],
                 album=Album(uri=plex_uri_method(plextrack.parentKey, 'plex:album'),
                             name=plextrack.parentTitle),
                 track_no=None, #plextrack.index,
                 length=plextrack.duration,
                 # TODO: bitrate=plextrack.media.bitrate,
                 comment=plextrack.summary
                )
Beispiel #17
0
def translator(data):
    albumartist_kwargs = {}
    album_kwargs = {}
    artist_kwargs = {}
    track_kwargs = {}

    def _retrieve(source_key, target_key, target):
        if source_key in data:
            target[target_key] = data[source_key]

    _retrieve(gst.TAG_ALBUM, 'name', album_kwargs)
    _retrieve(gst.TAG_TRACK_COUNT, 'num_tracks', album_kwargs)
    _retrieve(gst.TAG_ARTIST, 'name', artist_kwargs)

    if gst.TAG_DATE in data and data[gst.TAG_DATE]:
        date = data[gst.TAG_DATE]
        date = datetime.date(date.year, date.month, date.day)
        track_kwargs['date'] = date

    _retrieve(gst.TAG_TITLE, 'name', track_kwargs)
    _retrieve(gst.TAG_TRACK_NUMBER, 'track_no', track_kwargs)

    # Following keys don't seem to have TAG_* constant.
    _retrieve('album-artist', 'name', albumartist_kwargs)
    _retrieve('musicbrainz-trackid', 'musicbrainz_id', track_kwargs)
    _retrieve('musicbrainz-artistid', 'musicbrainz_id', artist_kwargs)
    _retrieve('musicbrainz-albumid', 'musicbrainz_id', album_kwargs)
    _retrieve('musicbrainz-albumartistid', 'musicbrainz_id',
              albumartist_kwargs)

    if albumartist_kwargs:
        album_kwargs['artists'] = [Artist(**albumartist_kwargs)]

    track_kwargs['uri'] = data['uri']
    track_kwargs['length'] = data[gst.TAG_DURATION]
    track_kwargs['album'] = Album(**album_kwargs)
    track_kwargs['artists'] = [Artist(**artist_kwargs)]

    return Track(**track_kwargs)
Beispiel #18
0
 def test_albumartist_tag_cache(self):
     tracks = parse_mpd_tag_cache(path_to_data_dir('albumartist_tag_cache'),
                                  path_to_data_dir(''))
     uri = path_to_uri(path_to_data_dir('song1.mp3'))
     artist = Artist(name='albumartistname')
     album = expected_albums[0].copy(artists=[artist])
     track = Track(name='trackname',
                   artists=expected_artists,
                   track_no=1,
                   album=album,
                   length=4000,
                   uri=uri)
     self.assertEqual(track, list(tracks)[0])
Beispiel #19
0
    def setUp(self):  # noqa: N802
        self.tags = {
            'album': ['album'],
            'track-number': [1],
            'artist': ['artist'],
            'composer': ['composer'],
            'performer': ['performer'],
            'album-artist': ['albumartist'],
            'title': ['track'],
            'track-count': [2],
            'album-disc-number': [2],
            'album-disc-count': [3],
            'date': [datetime.date(2006, 1, 1,)],
            'container-format': ['ID3 tag'],
            'genre': ['genre'],
            'comment': ['comment'],
            'musicbrainz-trackid': ['trackid'],
            'musicbrainz-albumid': ['albumid'],
            'musicbrainz-artistid': ['artistid'],
            'musicbrainz-sortname': ['sortname'],
            'musicbrainz-albumartistid': ['albumartistid'],
            'bitrate': [1000],
        }

        artist = Artist(name='artist', musicbrainz_id='artistid',
                        sortname='sortname')
        composer = Artist(name='composer')
        performer = Artist(name='performer')
        albumartist = Artist(name='albumartist',
                             musicbrainz_id='albumartistid')

        album = Album(name='album', num_tracks=2, num_discs=3,
                      musicbrainz_id='albumid', artists=[albumartist])

        self.track = Track(name='track', date='2006-01-01',
                           genre='genre', track_no=1, disc_no=2,
                           comment='comment', musicbrainz_id='trackid',
                           album=album, bitrate=1000, artists=[artist],
                           composers=[composer], performers=[performer])
Beispiel #20
0
 def get_items(self, uri):
     id_, upload = parse_uri(uri)
     logger.info("YTMusic getting playlist items for \"%s\"", id_)
     try:
         pls = API.get_playlist(id_, limit=100)
     except Exception:
         logger.exception("YTMusic failed getting playlist items")
         pls = None
     if pls:
         refs = []
         if "tracks" in pls:
             for track in pls["tracks"]:
                 refs.append(Ref.track(uri=f"ytm:video?id={track['videoId']}", name=track["title"]))
                 duration = track["duration"].split(":")
                 artists = [Artist(
                     uri=f"ytm:artist?id={a['id']}&upload=false",
                     name=a["name"],
                     sortname=a["name"],
                     musicbrainz_id="",
                 ) for a in track["artists"]]
                 if track["album"]:
                     album = Album(
                         uri=f"ytm:album?id={track['album']['id']}&upload=false",
                         name=track["album"]["name"],
                         artists=artists,
                         num_tracks=None,
                         num_discs=None,
                         date="1999",
                         musicbrainz_id="",
                     )
                 else:
                     album = None
                 TRACKS[track["videoId"]] = Track(
                     uri=f"ytm:video?id={track['videoId']}",
                     name=track["title"],
                     artists=artists,
                     album=album,
                     composers=[],
                     performers=[],
                     genre="",
                     track_no=None,
                     disc_no=None,
                     date="1999",
                     length=(int(duration[0]) * 60 * 1000) + (int(duration[1]) * 1000),
                     bitrate=0,
                     comment="",
                     musicbrainz_id="",
                     last_modified=None,
                 )
         return refs
     return None
Beispiel #21
0
    def _to_mopidy_artist(self, song):
        name = song.get('artist', '')
        uri = 'gmusic:artist:' + self._create_id(name)

        # First try to process the artist as an aa artist
        # (Difference being that non aa artists don't have artistId)
        try:
            artist = self._aa_to_mopidy_artist(song)
            self.artists[uri] = artist
            return artist
        except KeyError:
            artist = Artist(uri=uri, name=name)
            self.artists[uri] = artist
            return artist
Beispiel #22
0
 def _create_track(self, row):
     art_id = row[b'ArtworkID']
     images = [os.path.join(self.art_dir, art_id +
                            '.jpg')] if art_id else []
     artist = Artist(name=row[b'ArtistName'], )
     album = Album(name=row[b'AlbumName'], artists=[artist], images=images)
     track = Track(name=row[b'TrackName'],
                   track_no=row[b'TrackNumber'],
                   artists=[artist],
                   album=album,
                   uri=row[b'Uri'],
                   date=unicode(row[b'Year']),
                   length=row[b'Duration'])
     return track
Beispiel #23
0
 def test_albumartist_tag_cache(self):
     tracks = parse_mpd_tag_cache(path_to_data_dir('albumartist_tag_cache'),
                                  path_to_data_dir(''))
     artist = Artist(name='albumartistname')
     album = expected_albums[0].copy(artists=[artist])
     track = Track(uri='local:track:song1.mp3',
                   name='trackname',
                   artists=expected_artists,
                   track_no=1,
                   album=album,
                   date='2006',
                   length=4000,
                   last_modified=1272319626)
     self.assertEqual(track, list(tracks)[0])
Beispiel #24
0
 def test_eq(self):
     artists = [Artist()]
     album1 = Album(name='name',
                    uri='uri',
                    artists=artists,
                    num_tracks=2,
                    musicbrainz_id='id')
     album2 = Album(name='name',
                    uri='uri',
                    artists=artists,
                    num_tracks=2,
                    musicbrainz_id='id')
     self.assertEqual(album1, album2)
     self.assertEqual(hash(album1), hash(album2))
 def raw_album_to_album(self, album):
     if album is None:
         return None
     return Album(
         name=album.get("title") or album.get("name") or UNKNOWN_ALBUM,
         num_tracks=album.get("songCount"),
         uri=uri.get_album_uri(album.get("id")),
         artists=[
             Artist(
                 name=album.get("artist"),
                 uri=uri.get_artist_uri(album.get("artistId")),
             )
         ],
     )
    def parse_track(self, data, remote_url=False):
        if not data:
            return None
        if not data.get("streamable"):
            logger.info(
                f"{data.get('title')!r} can't be streamed from SoundCloud")
            return None
        if not data.get("kind") == "track":
            logger.debug(f"{data.get('title')} is not a track")
            return None

        track_kwargs = {}
        artist_kwargs = {}
        album_kwargs = {}

        if "title" in data:
            label_name = data.get("label_name")
            if not label_name:
                label_name = data.get("user", {}).get("username",
                                                      "Unknown label")

            track_kwargs["name"] = data["title"]
            artist_kwargs["name"] = label_name
            album_kwargs["name"] = "SoundCloud"

        if "date" in data:
            track_kwargs["date"] = data["date"]

        if remote_url:
            args = (data["sharing"], data["permalink_url"], data["stream_url"])
            track_kwargs["uri"] = self.get_streamable_url(*args)
            if track_kwargs["uri"] is None:
                logger.info(
                    f"{data.get('title')} can't be streamed from SoundCloud")
                return None
        else:
            track_kwargs[
                "uri"] = f"soundcloud:song/{readable_url(data.get('title'))}.{data.get('id')}"

        track_kwargs["length"] = int(data.get("duration", 0))
        track_kwargs["comment"] = data.get("permalink_url", "")

        if artist_kwargs:
            track_kwargs["artists"] = [Artist(**artist_kwargs)]

        if album_kwargs:
            track_kwargs["album"] = Album(**album_kwargs)

        return Track(**track_kwargs)
Beispiel #27
0
 def _find_artists(self, query):
     statement = ('select Distinct albumartist, mb_albumartistid'
                  ' from albums where 1=1 ')
     statement += self._build_statement(query, 'genre', 'genre')
     statement += self._build_statement(query, 'artist', 'albumartist')
     statement += self._build_statement(query, 'date', 'year')
     statement += self._build_statement(query, 'mb_albumartistid',
                                        'mb_albumartistid')
     artists = []
     result = self._query_beets_db(statement)
     for row in result:
         artists.append(
             Artist(name=row[0],
                    musicbrainz_id=row[1],
                    uri="beetslocal:artist:%s:" % row[1]))
     return artists
Beispiel #28
0
    def test_search(self):
        self.backend.library.dummy_search_result = SearchResult(
            albums=[Album(uri='dummy:album:a', name='A')],
            artists=[Artist(uri='dummy:artist:b', name='B')],
            tracks=[Track(uri='dummy:track:c', name='C')])

        self.send_request('search "any" "foo"')

        self.assertInResponse('file: dummy:album:a')
        self.assertInResponse('Title: Album: A')
        self.assertInResponse('file: dummy:artist:b')
        self.assertInResponse('Title: Artist: B')
        self.assertInResponse('file: dummy:track:c')
        self.assertInResponse('Title: C')

        self.assertInResponse('OK')
Beispiel #29
0
    def parse_track(self, data, remote_url=False):
        if not data:
            return None

        # NOTE kwargs dict keys must be bytestrings to work on Python < 2.6.5
        # See https://github.com/mopidy/mopidy/issues/302 for details.

        track_kwargs = {}
        artist_kwargs = {}
        album_kwargs = {}

        if STR_NAME in data:
            name = data[STR_NAME]
            label_name = data.get(STR_NAME)

            if bool(label_name):
                track_kwargs[b'name'] = name
                artist_kwargs[b'name'] = label_name
            else:
                track_kwargs[b'name'] = name
                artist_kwargs[b'name'] = data[STR_USER]['name']

            album_kwargs[b'name'] = 'Mixcloud'

        if STR_DATE in data:
            track_kwargs[b'date'] = data[STR_DATE]

        track_kwargs[b'uri'] = 'mixcloud:' + data.get('key')

        track_kwargs[b'length'] = int(data.get('duration', 0))
        track_kwargs[b'comment'] = data.get('permalink_url', '')

        if artist_kwargs:
            artist = Artist(**artist_kwargs)
            track_kwargs[b'artists'] = [artist]
        """if album_kwargs:
            if 'artwork_url' in data and data['artwork_url']:
                album_kwargs[b'images'] = [data['artwork_url']]
            else:
                image = data.get('user').get('avatar_url')
                album_kwargs[b'images'] = [image]

            album = Album(**album_kwargs)
            track_kwargs[b'album'] = album
        """
        track = Track(**track_kwargs)
        return track
 def albumToTracks(self, album, bId):
     ret = []
     date = f"{album['releaseDate']['year']}"
     artists = []
     for artist in album['artist']:
         if artist['id'] not in self.ARTISTS:
             self.ARTISTS[artist['id']] = Artist(
                 uri=f"youtubemusic:artist:{artist['id']}",
                 name=artist["name"],
                 sortname=artist["name"],
                 musicbrainz_id="",
             )
         artists.append(self.ARTISTS[artist['id']])
     if bId not in self.ALBUMS:
         self.ALBUMS[bId] = Album(
             uri=f"youtubemusic:album:{bId}",
             name=album["title"],
             artists=artists,
             num_tracks=int(album["trackCount"])
             if str(album["trackCount"]).isnumeric() else None,
             num_discs=None,
             date=date,
             musicbrainz_id="",
         )
     for song in album["tracks"]:
         if song['videoId'] not in self.TRACKS:
             self.TRACKS[song["videoId"]] = Track(
                 uri=f"youtubemusic:track:{song['videoId']}",
                 name=song["title"],
                 artists=artists,
                 album=self.ALBUMS[bId],
                 composers=[],
                 performers=[],
                 genre="",
                 track_no=int(song["index"])
                 if str(song["index"]).isnumeric() else None,
                 disc_no=None,
                 date=date,
                 length=int(song["lengthMs"])
                 if str(song["lengthMs"]).isnumeric() else None,
                 bitrate=0,
                 comment="",
                 musicbrainz_id="",
                 last_modified=None,
             )
         ret.append(self.TRACKS[song['videoId']])
     return (ret)