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

Code before:
                'chapters': [{
                    'start_time': chapter.get('time'),
                    'end_time': try_get(chapter, lambda x: x['time'] + x['duration']),
                    'title': chapter.get('text'),
                } for chapter in item['cuepoints']] if item.get('cuepoints') and type_ == 'concert' else None,
            }

    def _real_extract(self, url):
        language, type_, video_id, part = self._match_valid_url(url).group('language', 'type', 'id', 'part')
        if not language:
            language = 'en'

        api_type = 'concert' if type_ == 'work' else type_
        vid_info = self._download_json(
            f'https://api.digitalconcerthall.com/v2/{api_type}/{video_id}', video_id, headers={
                'Accept': 'application/json',
                'Accept-Language': language,
                'User-Agent': self._USER_AGENT,
                'Authorization': f'Bearer {self._ACCESS_TOKEN}',
            })
        videos = [vid_info] if type_ == 'film' else traverse_obj(vid_info, ('_embedded', ..., ...))

        if type_ == 'work':
            videos = [videos[int(part) - 1]]

        album_artists = traverse_obj(vid_info, ('_links', 'artist', ..., 'name'))
        thumbnail = traverse_obj(vid_info, (
            'image', ..., {self._proto_relative_url}, {url_or_none},
            {lambda x: x.format(width=0, height=0)}, any))  # NB: 0x0 is the original size

        return {
            '_type': 'playlist',
            'id': video_id,
            'title': vid_info.get('title'),
            'entries': self._entries(
                videos, language, type_, thumbnail=thumbnail, album_artists=album_artists),
            'thumbnail': thumbnail,
            'album_artists': album_artists,
        }


Review comment (suggestion):
```suggestion
        album_artists = traverse_obj(vid_info, ('_links', 'artist', ..., 'name', {str}))
```

Code after:
                **kwargs,
                'chapters': [{
                    'start_time': chapter.get('time'),
                    'end_time': try_get(chapter, lambda x: x['time'] + x['duration']),
                    'title': chapter.get('text'),
                } for chapter in item['cuepoints']] if item.get('cuepoints') and type_ == 'concert' else None,
            }

    def _real_extract(self, url):
        language, type_, video_id, part = self._match_valid_url(url).group('language', 'type', 'id', 'part')
        if not language:
            language = 'en'

        api_type = 'concert' if type_ == 'work' else type_
        vid_info = self._download_json(
            f'https://api.digitalconcerthall.com/v2/{api_type}/{video_id}', video_id, headers={
                'Accept': 'application/json',
                'Accept-Language': language,
                'User-Agent': self._USER_AGENT,
                'Authorization': f'Bearer {self._ACCESS_TOKEN}',
            })
        videos = [vid_info] if type_ == 'film' else traverse_obj(vid_info, ('_embedded', ..., ...))

        if type_ == 'work':
            videos = [videos[int(part) - 1]]

        album_artists = traverse_obj(vid_info, ('_links', 'artist', ..., 'name', {str}))
        thumbnail = traverse_obj(vid_info, (
            'image', ..., {self._proto_relative_url}, {url_or_none},
            {lambda x: x.format(width=0, height=0)}, any))  # NB: 0x0 is the original size

        return {
            '_type': 'playlist',
            'id': video_id,
            'title': vid_info.get('title'),
            'entries': self._entries(
                videos, language, type_, thumbnail=thumbnail, album_artists=album_artists),
            'thumbnail': thumbnail,
            'album_artists': album_artists,
        }