ytdl-org/youtube-dl · warning · ExtractorError

%s is offline

Error message

%s is offline

What it means

ShowRoomLiveIE._real_extract fetches the room profile from /api/room/profile and checks the 'is_onlive' field. If it is not exactly True (the broadcaster is not currently streaming), the extractor raises '<broadcaster> is offline' as an expected error. SHOWROOM is a live-only platform, so there is nothing to extract from an offline room.

Source

Thrown at youtube_dl/extractor/showroomlive.py:35

        'only_matching': True,
    }

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

        webpage = self._download_webpage(url, broadcaster_id)

        room_id = self._search_regex(
            (r'SrGlobal\.roomId\s*=\s*(\d+)',
             r'(?:profile|room)\?room_id\=(\d+)'), webpage, 'room_id')

        room = self._download_json(
            urljoin(url, '/api/room/profile?room_id=%s' % room_id),
            broadcaster_id)

        is_live = room.get('is_onlive')
        if is_live is not True:
            raise ExtractorError('%s is offline' % broadcaster_id, expected=True)

        uploader = room.get('performer_name') or broadcaster_id
        title = room.get('room_name') or room.get('main_name') or uploader

        streaming_url_list = self._download_json(
            urljoin(url, '/api/live/streaming_url?room_id=%s' % room_id),
            broadcaster_id)['streaming_url_list']

        formats = []
        for stream in streaming_url_list:
            stream_url = stream.get('url')
            if not stream_url:
                continue
            stream_type = stream.get('type')
            if stream_type == 'hls':
                m3u8_formats = self._extract_m3u8_formats(
                    stream_url, broadcaster_id, ext='mp4', m3u8_id='hls',
                    live=True)

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Wait until the broadcaster is actually live and retry (verify by opening the room in a browser).
  2. If you need the past stream, look for the broadcaster's recorded archives on SHOWROOM's replay feature or their uploads elsewhere.
  3. Confirm the room id in the URL matches the broadcaster's current room (rooms can be recreated with new ids).
  4. For automation, poll the /api/room/profile?room_id= endpoint yourself and only invoke youtube-dl when is_onlive is true.

Example fix

// before
is_live = room.get('is_onlive')
if is_live is not True:
    raise ExtractorError('%s is offline' % broadcaster_id, expected=True)

// after (caller-side gate in a wrapper script)
import json, urllib.request
profile = json.load(urllib.request.urlopen(
    'https://www.showroom-live.com/api/room/profile?room_id=%s' % room_id))
if profile.get('is_onlive') is not True:
    print('offline; not invoking youtube-dl')
else:
    subprocess.run(['youtube-dl', url])
Defensive patterns

Strategy: validation

Validate before calling

profile = json.load(urllib.request.urlopen(
    'https://www.showroom-live.com/api/room/profile?room_id=' + room_id))
if profile.get('is_onlive') is not True:
    print('offline - not extracting'); exit(0)

Type guard

def room_is_live(profile: dict) -> bool:
    return profile.get('is_onlive') is True

Try / catch

try:
    extract(url)
except ExtractorError as e:
    if 'is offline' in str(e):
        schedule_retry(later=True)
    else:
        raise

Prevention

When it happens

Trigger: Extracting a showroom-live.jp room URL while the broadcaster is offline: room.get('is_onlive') returns None, 0, or false. The profile API is still reachable and returns valid JSON; the error is purely the live-state check.

Common situations: Downloading a room URL after a stream ended; scheduling downloads against a room that has not started; the broadcaster being on a different platform/room id; time-zone confusion about when a stream is live.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/1109c8a5538848f0. Report an issue: GitHub.