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

Code before:
                'redirect_uri': 'https://www.tennistv.com/resources/v1.1.10/html/silent-check-sso.html'
            })
            return

        if cookies.get('access_token') and cookies.get('refresh_token') is not None:
            self.ACCESS_TOKEN = cookies.get('access_token').value
            self.REFRESH_TOKEN = cookies.get('refresh_token').value
            return

        else:
            self.report_warning('Site requires a subscribed account. Either pass in the cookies or login credentials.')

    def get_token(self, video_id, payload):
        res = self._download_json('https://sso.tennistv.com/auth/realms/TennisTV/protocol/openid-connect/token', video_id,
                                  'Fetching tokens', 'Unable to fetch tokens', headers=self.headers,
                                  data=urlencode_postdata(payload))

        self.ACCESS_TOKEN = res.get('access_token')
        self.REFRESH_TOKEN = res.get('refresh_token')

    def _real_initialize(self):
        self._login()

    def _download_session_json(self, video_id, entryid,):
        return self._download_json(f'https://atppayments.streamamg.com/api/v1/session/ksession/?lang=en&apijwttoken={self.ACCESS_TOKEN}&entryId={entryid}',
                                   video_id, 'Downloading ksession token', 'Failed to download ksession token', headers=self.headers)

    def _real_extract(self, url):
        video_id = self._match_id(url)
        webpage = self._download_webpage(url, video_id)

        title = self._html_search_regex((r'<title>(.+?)</title>', *self._og_regexes('title')),
                                        webpage, 'Title', fatal=False)

        entryid = self._search_regex(r'data-entry-id=["\']([^"\']+)', webpage, 'entryID')

        session_json = self._download_session_json(video_id, entryid)

        k_session = session_json.get('KSession')
        if k_session is None:

            # retry with fresh tokens
            self.get_token(video_id, {
                'grant_type': 'refresh_token',
                'refresh_token': self.REFRESH_TOKEN,
                'client_id': 'tennis-tv-web'
            })
            k_session = self._download_session_json(video_id, entryid).get('KSession')

            if k_session is None:
                raise ExtractorError('Failed to get KSession, possibly a premium video', expected=True)

Review comment (bug):
```suggestion
        return self._download_json(
            f'https://atppayments.streamamg.com/api/v1/session/ksession/?lang=en&apijwttoken={self.ACCESS_TOKEN}&entryId={entryid}',
            video_id, 'Downloading ksession token', 'Failed to download ksession token', headers=self.headers)
```

Code after:
            'redirect_uri': 'https://www.tennistv.com/resources/v1.1.10/html/silent-check-sso.html'
        })

    def get_token(self, video_id, payload):
        res = self._download_json(
            f'{self._AUTH_BASE_URL}/token', video_id, 'Fetching tokens',
            'Unable to fetch tokens', headers=self._HEADERS, data=urlencode_postdata(payload))

        self.access_token = res.get('access_token') or self.access_token
        self.refresh_token = res.get('refresh_token') or self.refresh_token

    def _real_initialize(self):
        if self.access_token and self.refresh_token:
            return

        cookies = self._get_cookies('https://www.tennistv.com/')
        if not cookies.get('access_token') or not cookies.get('refresh_token'):
            self.raise_login_required()
        self.access_token, self.refresh_token = cookies['access_token'].value, cookies['refresh_token'].value

    def _download_session_json(self, video_id, entryid,):
        return self._download_json(
            f'https://atppayments.streamamg.com/api/v1/session/ksession/?lang=en&apijwttoken={self.access_token}&entryId={entryid}',
            video_id, 'Downloading ksession token', 'Failed to download ksession token', headers=self._HEADERS)

    def _real_extract(self, url):
        video_id = self._match_id(url)
        webpage = self._download_webpage(url, video_id)

        entryid = self._search_regex(r'data-entry-id=["\']([^"\']+)', webpage, 'entryID')
        session_json = self._download_session_json(video_id, entryid)

        k_session = session_json.get('KSession')
        if k_session is None:
            self.get_token(video_id, {
                'grant_type': 'refresh_token',
                'refresh_token': self.refresh_token,
                'client_id': 'tennis-tv-web'
            })
            k_session = self._download_session_json(video_id, entryid).get('KSession')
            if k_session is None:
                raise ExtractorError('Failed to get KSession, possibly a premium video', expected=True)

        if session_json.get('ErrorMessage'):
            self.report_warning(session_json['ErrorMessage'])

        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
            self._FORMAT_URL.format(partner=self._PARTNER_ID, entry=entryid, session=k_session), video_id)

        self._sort_formats(formats)