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

Code before:

        return self.playlist_result(entries, season_id, video_info.get('title'))


class RadLiveChannelIE(RadLiveIE):
    IE_NAME = 'radlive:channel'
    _VALID_URL = r'https?://(?:www\.)?rad\.live/content/channel/(?P<id>[a-f0-9-]+)'
    _TESTS = [{
        'url': 'https://rad.live/content/channel/5c4d8df4-6fa0-413c-81e3-873479b49274',
        'md5': '625156a08b7f2b0b849f234e664457ac',
        'info_dict': {
            'id': '5c4d8df4-6fa0-413c-81e3-873479b49274',
            'title': 'Whistle Sports',
        },
        'playlist_mincount': 7,
    }]

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

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

        data = self._download_json('https://content.mhq.12core.net/graphql', channel_id, data=json.dumps({
            'query': """
query WebChannelListing ($lrn: ID!) {
  channel (id:$lrn) {
  ...Channel

    metadata {
      ...Metadata
    }

    presentation {
      ...Presentation
    }

    miniseries {
      ...Miniseries
      metadata {
        ...Metadata
      }

      presentation {
        ...Presentation
      }
      episodes {
        ...Episode
      }
    }

Review comment (suggestion):
The query seems just copy pasted from website. It would be better if you can construct a proper query with only the necessary fields. See https://github.com/yt-dlp/yt-dlp/pull/717#pullrequestreview-731222664

Code after:

        return self.playlist_result(entries, season_id, video_info.get('title'))


class RadLiveChannelIE(RadLiveIE):
    IE_NAME = 'radlive:channel'
    _VALID_URL = r'https?://(?:www\.)?rad\.live/content/channel/(?P<id>[a-f0-9-]+)'
    _TESTS = [{
        'url': 'https://rad.live/content/channel/5c4d8df4-6fa0-413c-81e3-873479b49274',
        'md5': '625156a08b7f2b0b849f234e664457ac',
        'info_dict': {
            'id': '5c4d8df4-6fa0-413c-81e3-873479b49274',
            'title': 'Whistle Sports',
        },
        'playlist_mincount': 7,
    }]

    _QUERY = '''
query WebChannelListing ($lrn: ID!) {
  channel (id:$lrn) {
    name
    features {
      structured_data
    }
  }
}'''

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

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

        graphql = self._download_json(
            'https://content.mhq.12core.net/graphql', channel_id,
            headers={'Content-Type': 'application/json'},
            data=json.dumps({
                'query': self._QUERY,
                'variables': {'lrn': f'lrn:12core:media:content:channel:{channel_id}'}
            }).encode('utf-8'))

        data = traverse_obj(graphql, ('data', 'channel'))
        if not data:
            raise ExtractorError('Unable to extract video info, make sure the URL is valid')

        entries = [{
            '_type': 'url_transparent',
            'url': feature['structured_data']['url'],
            'ie_key': RadLiveIE.ie_key(),
        } for feature in data['features']]