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

Code before:
        info_dict = self._extract_video(data, video_id)
        if not info_dict.get('title'):
            title = dict_get(info_dict, ('episode', 'series'))
            if not title and webpage:
                title = re.sub(
                    r'\s*\|\s*.+?$', '', self._og_search_title(webpage))
            if not title:
                title = video_id
            info_dict['title'] = title
        return info_dict

    def _real_extract(self, url):
        mobj = self._match_valid_url(url)
        video_id = mobj.group('id')
        svt_id = mobj.group('svt_id') or mobj.group('modal_id')
        if svt_id:
            return self._extract_by_video_id(svt_id)

        webpage = self._download_webpage(url, video_id)

        data = traverse_obj(self._search_nextjs_data(webpage, video_id), (
            'props', 'urqlState', ..., 'data', {json.loads},
            'detailsPageByPath', {dict}, any, {require('video data')}))
        details = traverse_obj(data, (
            'modules', lambda _, v: v['details']['smartStart']['item']['videos'],
            'details', {dict}, any))
        svt_id = traverse_obj(details, (
            'smartStart', 'item', 'videos',
            # There can be 'AudioDescribed' and 'SignInterpreted' variants; try 'Default' or else get first
            (lambda _, v: v['accessibility'] == 'Default', 0),
            'svtId', {str}, any))
        if not svt_id:
            svt_id = traverse_obj(data, ('video', 'svtId', {str}, {require('SVT ID')}))

        info_dict = self._extract_by_video_id(svt_id, webpage)
        if not info_dict.get('description'):
            info_dict['description'] = traverse_obj(details, ('description', {str}))
        info_dict['thumbnail'] = self._og_search_thumbnail(webpage)

        return info_dict


class SVTSeriesIE(SVTPlayBaseIE):
    _VALID_URL = r'https?://(?:www\.)?svtplay\.se/(?P<id>[^/?&#]+)(?:.+?\btab=(?P<season_slug>[^&#]+))?'
    _TESTS = [{
        'url': 'https://www.svtplay.se/rederiet',
        'info_dict': {
            'id': '14445680',
            'title': 'Rederiet',
            'description': 'md5:d9fdfff17f5d8f73468176ecd2836039',
        },

Review comment (suggestion):
as pointed out by dirkf, the `{dict}` check is redundant
```suggestion
            'modules', lambda _, v: v['details']['smartStart']['item']['videos'], 'details', any))
```

Code after:
        if not info_dict.get('title'):
            info_dict['title'] = re.sub(r'\s*\|\s*.+?$', '', self._og_search_title(webpage))
        if not info_dict.get('thumbnail'):
            info_dict['thumbnail'] = self._og_search_thumbnail(webpage)
        if not info_dict.get('description'):
            info_dict['description'] = traverse_obj(details, ('description', {str}))

        return info_dict


class SVTSeriesIE(SVTBaseIE):
    IE_NAME = 'svt:play:series'
    _VALID_URL = r'https?://(?:www\.)?svtplay\.se/(?P<id>[^/?&#]+)(?:.+?\btab=(?P<season_slug>[^&#]+))?'
    _TESTS = [{
        'url': 'https://www.svtplay.se/rederiet',
        'info_dict': {
            'id': 'jpmQYgn',
            'title': 'Rederiet',
            'description': 'md5:f71122f7cf2e52b643e75915e04cb83d',
        },
        'playlist_mincount': 318,
    }, {
        'url': 'https://www.svtplay.se/rederiet?tab=season-2-jpmQYgn',
        'info_dict': {
            'id': 'season-2-jpmQYgn',
            'title': 'Rederiet - Säsong 2',
            'description': 'md5:f71122f7cf2e52b643e75915e04cb83d',
        },
        'playlist_mincount': 12,
    }]

    @classmethod
    def suitable(cls, url):
        return False if SVTPlayIE.suitable(url) else super().suitable(url)

    def _real_extract(self, url):
        series_slug, season_id = self._match_valid_url(url).groups()

        series = self._download_json(
            'https://api.svt.se/contento/graphql', series_slug,
            'Downloading series page', query={
                'query': '''{
  listablesBySlug(slugs: ["%s"]) {
    associatedContent(include: [productionPeriod, season]) {
      items {
        item {
          ... on Episode {
            videoSvtId
          }
        }
      }