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

Code before:
        entries = self._generate_event_playlist(event_data)
        return self.playlist_result(entries, event_id, event_data['full_name'])

    def _extract_account_events(self, account_data):
        upcoming_events = account_data['upcoming_events']
        past_events = account_data['past_events']
        entries = []
        events = upcoming_events['data'] + past_events['data']
        for event_data in events:
            playlist = self._generate_event_playlist(event_data)
            if playlist:
                entries = entries + playlist
        return self.playlist_result(entries, account_data['id'], account_data['full_name'])

    def _real_extract(self, url):
        mobj = self._match_valid_url(url)
        video_id = mobj.group('id')
        event = mobj.group('event_id') or mobj.group('event_name')
        account = mobj.group('account_id') or mobj.group('account_name')
        api_url = self._ACCOUNT_API_URL_TEMPLATE % (account)
        if video_id:
            video_data = self._download_json(
                api_url + '/events/%s' % event + '/videos/%s' % video_id, video_id)
            return self._extract_video_info(video_data)
        if event:
            event_data = self._download_json(api_url + '/events/%s' % event, None)
            return self._extract_event(event_data)
        account_data = self._download_json(api_url, None)
        return self._extract_account_events(account_data)


# The original version of Livestream uses a different system
class LivestreamOriginalIE(InfoExtractor):
    IE_NAME = 'livestream:original'
    _VALID_URL = r'''(?x)https?://original\.livestream\.com/
        (?P<user>[^/\?#]+)(?:/(?P<type>video|folder)
        (?:(?:\?.*?Id=|/)(?P<id>.*?)(&|$))?)?
        '''
    _TESTS = [{
        'url': 'http://original.livestream.com/dealbook/video?clipId=pla_8aa4a3f1-ba15-46a4-893b-902210e138fb',
        'info_dict': {
            'id': 'pla_8aa4a3f1-ba15-46a4-893b-902210e138fb',
            'ext': 'mp4',
            'title': 'Spark 1 (BitCoin) with Cameron Winklevoss & Tyler Winklevoss of Winklevoss Capital',
            'duration': 771.301,
            'view_count': int,
        },
    }, {
        'url': 'https://original.livestream.com/newplay/folder?dirId=a07bf706-d0e4-4e75-a747-b021d84f2fd3',
        'info_dict': {
            'id': 'a07bf706-d0e4-4e75-a747-b021d84f2fd3',

Review comment (refactor):
```suggestion
        api_url = f'http://livestream.com/api/accounts/{account}'
        if video_id:
            video_data = self._download_json(
                 f'{api_url}/events/{event}/videos/{video_id}', video_id)
            return self._extract_video_info(video_data)
        elif event:
            event_data = self._download_json(f'{api_url}/events/{event}', None)
```

Code after:
        video_id = mobj.group('id')
        event = mobj.group('event_id') or mobj.group('event_name')
        account = mobj.group('account_id') or mobj.group('account_name')
        api_url = f'http://livestream.com/api/accounts/{account}'

        if video_id:
            video_data = self._download_json(
                f'{api_url}/events/{event}/videos/{video_id}', video_id)
            return self._extract_video_info(video_data)
        elif event:
            event_data = self._download_json(f'{api_url}/events/{event}', None)
            return self.playlist_result(
                self._generate_event_playlist(event_data), str(event_data['id']), event_data['full_name'])

        account_data = self._download_json(api_url, None)
        items = traverse_obj(account_data, (('upcoming_events', 'past_events'), 'data', ...))
        return self.playlist_result(
            itertools.chain.from_iterable(map(self._generate_event_playlist, items)),
            account_data.get('id'), account_data.get('full_name'))


# The original version of Livestream uses a different system
class LivestreamOriginalIE(InfoExtractor):
    IE_NAME = 'livestream:original'
    _VALID_URL = r'''(?x)https?://original\.livestream\.com/
        (?P<user>[^/\?#]+)(?:/(?P<type>video|folder)
        (?:(?:\?.*?Id=|/)(?P<id>.*?)(&|$))?)?
        '''
    _TESTS = [{
        'url': 'http://original.livestream.com/dealbook/video?clipId=pla_8aa4a3f1-ba15-46a4-893b-902210e138fb',
        'info_dict': {
            'id': 'pla_8aa4a3f1-ba15-46a4-893b-902210e138fb',
            'ext': 'mp4',
            'title': 'Spark 1 (BitCoin) with Cameron Winklevoss & Tyler Winklevoss of Winklevoss Capital',
            'duration': 771.301,
            'view_count': int,
        },
    }, {
        'url': 'https://original.livestream.com/newplay/folder?dirId=a07bf706-d0e4-4e75-a747-b021d84f2fd3',
        'info_dict': {
            'id': 'a07bf706-d0e4-4e75-a747-b021d84f2fd3',
        },
        'playlist_mincount': 4,
    }, {
        # live stream
        'url': 'http://original.livestream.com/znsbahamas',
        'only_matching': True,
    }]

    def _extract_video_info(self, user, video_id):
        api_url = 'http://x%sx.api.channel.livestream.com/2.0/clipdetails?extendedInfo=true&id=%s' % (user, video_id)