Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/neteasemusic.py (Python)

Code before:

        info = self.query_api(
            f'song/detail?id={song_id}&ids=%5B{song_id}%5D', song_id, 'Downloading song info')['songs'][0]

        formats = self.extract_formats(info)

        lyrics = self._process_lyrics(self.query_api(
            f'song/lyric?id={song_id}&lv=-1&tv=-1', song_id, 'Downloading lyrics data'))
        lyric_data = {
            'description': traverse_obj(lyrics, (('lyrics_merged', 'lyrics'), 0, 'data'), get_all=False),
            'subtitles': lyrics,
        } if lyrics else {}

        return {
            'id': song_id,
            'formats': formats,
            'alt_title': '/'.join(traverse_obj(info, (('transNames', 'alias'), ...))) or None,
            'creator': ' / '.join(traverse_obj(info, ('artists', ..., 'name'))) or None,
            'album_artist': ' / '.join(traverse_obj(info, ('album', 'artists', ..., 'name'))) or None,
            **lyric_data,
            **traverse_obj(info, {
                'title': ('name', {str}),
                'timestamp': ('album', 'publishTime', {self.kilo_or_none}),
                'duration': ('duration', {self.kilo_or_none}),
                'album': ('album', 'name', {url_or_none}),
                'thumbnail': ('album', 'picUrl', {str_or_none}),
                'average_rating': ('score', {int_or_none}),
            }),
        }


class NetEaseMusicAlbumIE(NetEaseMusicBaseIE):
    IE_NAME = 'netease:album'
    IE_DESC = '网易云音乐 - 专辑'
    _VALID_URL = r'https?://music\.163\.com/(#/)?album\?id=(?P<id>[0-9]+)'
    _TESTS = [{
        'url': 'https://music.163.com/#/album?id=133153666',
        'info_dict': {
            'id': '133153666',
            'title': '桃几的翻唱',
            'upload_date': '20210913',
            'description': '桃几2021年翻唱合集',
            'thumbnail': r're:^http.*\.jpg',
        },
        'playlist_mincount': 13,
    }, {
        'url': 'http://music.163.com/#/album?id=220780',
        'info_dict': {
            'id': '220780',
            'title': 'B\'Day',
            'upload_date': '20060904',

Review comment (suggestion):
```suggestion
                'thumbnail': ('album', 'picUrl', {url_or_none}),
                'duration': ('duration', {self.kilo_or_none}),
                'album': ('album', 'name', {str}),
```

Code after:
        original_ts_texts = re.findall(lyrics_expr, original)
        translation_ts_dict = dict(re.findall(lyrics_expr, translated))

        merged = '\n'.join(
            join_nonempty(f'{timestamp}{text}', translation_ts_dict.get(timestamp, ''), delim=' / ')
            for timestamp, text in original_ts_texts)

        return {
            'lyrics_merged': [{'data': merged, 'ext': 'lrc'}],
            'lyrics': [{'data': original, 'ext': 'lrc'}],
            'lyrics_translated': [{'data': translated, 'ext': 'lrc'}],
        }

    def _real_extract(self, url):
        song_id = self._match_id(url)

        info = self.query_api(
            f'song/detail?id={song_id}&ids=%5B{song_id}%5D', song_id, 'Downloading song info')['songs'][0]

        formats = self.extract_formats(info)

        lyrics = self._process_lyrics(self.query_api(
            f'song/lyric?id={song_id}&lv=-1&tv=-1', song_id, 'Downloading lyrics data'))
        lyric_data = {
            'description': traverse_obj(lyrics, (('lyrics_merged', 'lyrics'), 0, 'data'), get_all=False),
            'subtitles': lyrics,
        } if lyrics else {}

        return {
            'id': song_id,
            'formats': formats,
            'alt_title': '/'.join(traverse_obj(info, (('transNames', 'alias'), ...))) or None,
            'creator': ' / '.join(traverse_obj(info, ('artists', ..., 'name'))) or None,
            'album_artist': ' / '.join(traverse_obj(info, ('album', 'artists', ..., 'name'))) or None,
            **lyric_data,
            **traverse_obj(info, {
                'title': ('name', {str}),
                'timestamp': ('album', 'publishTime', {self.kilo_or_none}),
                'thumbnail': ('album', 'picUrl', {url_or_none}),
                'duration': ('duration', {self.kilo_or_none}),
                'album': ('album', 'name', {str}),
                'average_rating': ('score', {int_or_none}),
            }),
        }


class NetEaseMusicAlbumIE(NetEaseMusicBaseIE):
    IE_NAME = 'netease:album'
    IE_DESC = '网易云音乐 - 专辑'
    _VALID_URL = r'https?://music\.163\.com/(#/)?album\?id=(?P<id>[0-9]+)'
    _TESTS = [{