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

Code before:
        if display_id.startswith('$/'):
            display_id = display_id.split('/', 2)[-1].replace('/', ':')
        else:
            display_id = display_id.replace(':', '#')
        display_id = compat_urllib_parse_unquote(display_id)
        uri = 'lbry://' + display_id
        result = self._resolve_url(uri, display_id, 'stream')
        headers = {'Referer': 'https://odysee.com/'}
        if result['value'].get('stream_type') in self._SUPPORTED_STREAM_TYPES:
            claim_id, is_live = result['claim_id'], False
            streaming_url = self._call_api_proxy(
                'get', claim_id, {'uri': uri}, 'streaming url')['streaming_url']
            final_url = self._request_webpage(
                HEADRequest(streaming_url), display_id, headers=headers,
                note='Downloading streaming redirect url info').geturl()
        elif result.get('value_type') == 'stream':
            claim_id, is_live = result['signing_channel']['claim_id'], True
            live_data = self._download_json(
                'https://api.odysee.live/livestream/is_live', claim_id,
                query={'channel_claim_id': claim_id},
                note='Downloading livestream JSON metadata')['data']
            if 'VideoURL' not in live_data or live_data.get('Live') is False:
                streaming_url = final_url = None
                self.raise_no_formats('This stream is not live', True, claim_id)
            else:
                streaming_url = final_url = live_data.get('VideoURL')
        else:
            raise UnsupportedError(url)

        info = self._parse_stream(result, url)
        if determine_ext(final_url) == 'm3u8':
            info['formats'] = self._extract_m3u8_formats(
                final_url, display_id, 'mp4', 'm3u8_native', m3u8_id='hls', live=is_live, headers=headers)
            self._sort_formats(info['formats'])
        else:
            info['url'] = streaming_url
        return {
            **info,
            'id': claim_id,
            'title': result['value']['title'],
            'is_live': is_live,
            'http_headers': headers,
        }


class LBRYChannelIE(LBRYBaseIE):
    IE_NAME = 'lbry:channel'
    _VALID_URL = LBRYBaseIE._BASE_URL_REGEX + r'(?P<id>@%s)/?(?:[?&]|$)' % LBRYBaseIE._OPT_CLAIM_ID
    _TESTS = [{
        'url': 'https://lbry.tv/@LBRYFoundation:0',
        'info_dict': {

Review comment (suggestion):
```suggestion
            streaming_url = final_url = live_data.get('VideoURL')
            # Upcoming videos may still give VideoURL
            if not live_data.get('Live'):
                streaming_url = final_url = None
                self.raise_no_formats('This stream is not live', True, claim_id)
```

Code after:
        if display_id.startswith('$/'):
            display_id = display_id.split('/', 2)[-1].replace('/', ':')
        else:
            display_id = display_id.replace(':', '#')
        display_id = compat_urllib_parse_unquote(display_id)
        uri = 'lbry://' + display_id
        result = self._resolve_url(uri, display_id, 'stream')
        headers = {'Referer': 'https://odysee.com/'}
        if result['value'].get('stream_type') in self._SUPPORTED_STREAM_TYPES:
            claim_id, is_live = result['claim_id'], False
            streaming_url = self._call_api_proxy(
                'get', claim_id, {'uri': uri}, 'streaming url')['streaming_url']
            final_url = self._request_webpage(
                HEADRequest(streaming_url), display_id, headers=headers,
                note='Downloading streaming redirect url info').geturl()
        elif result.get('value_type') == 'stream':
            claim_id, is_live = result['signing_channel']['claim_id'], True
            live_data = self._download_json(
                'https://api.odysee.live/livestream/is_live', claim_id,
                query={'channel_claim_id': claim_id},
                note='Downloading livestream JSON metadata')['data']
            streaming_url = final_url = live_data.get('VideoURL')
            # Upcoming videos may still give VideoURL
            if not live_data.get('Live'):
                streaming_url = final_url = None
                self.raise_no_formats('This stream is not live', True, claim_id)
        else:
            raise UnsupportedError(url)

        info = self._parse_stream(result, url)
        if determine_ext(final_url) == 'm3u8':
            info['formats'] = self._extract_m3u8_formats(
                final_url, display_id, 'mp4', 'm3u8_native', m3u8_id='hls', live=is_live, headers=headers)
            self._sort_formats(info['formats'])
        else:
            info['url'] = streaming_url
        return {
            **info,
            'id': claim_id,
            'title': result['value']['title'],
            'is_live': is_live,
            'http_headers': headers,
        }


class LBRYChannelIE(LBRYBaseIE):
    IE_NAME = 'lbry:channel'
    _VALID_URL = LBRYBaseIE._BASE_URL_REGEX + r'(?P<id>@%s)/?(?:[?&]|$)' % LBRYBaseIE._OPT_CLAIM_ID
    _TESTS = [{
        'url': 'https://lbry.tv/@LBRYFoundation:0',
        'info_dict': {