{"record":{"id":"b4fc47fe64444313","repo":"yt-dlp/yt-dlp","slug":"this-livestream-has-ended","errorCode":null,"errorMessage":"This livestream has ended","messagePattern":"This livestream has ended","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"yt_dlp/extractor/afreecatv.py","lineNumber":399,"sourceCode":"        if channel_info.get('BPWD') == 'Y' and password is None:\n            raise ExtractorError(\n                'This livestream is protected by a password, use the --video-password option',\n                expected=True)\n\n        token_info = traverse_obj(self._download_json(\n            self._LIVE_API_URL, broadcast_no, 'Downloading access token for stream',\n            'Unable to download access token for stream', data=urlencode_postdata(filter_dict({\n                'bno': broadcast_no,\n                'stream_type': 'common',\n                'type': 'aid',\n                'quality': 'master',\n                'pwd': password,\n            }))), ('CHANNEL', {dict})) or {}\n        aid = token_info.get('AID')\n        if not aid:\n            result = token_info.get('RESULT')\n            if result == 0:\n                raise ExtractorError('This livestream has ended', expected=True)\n            elif result == -6:\n                self.raise_login_required('This livestream is for subscribers only', method='password')\n            raise ExtractorError('Unable to extract access token')\n\n        formats = self._extract_formats(channel_info, broadcast_no, aid)\n\n        station_info = traverse_obj(self._download_json(\n            'https://st.sooplive.com/api/get_station_status.php', broadcast_no,\n            'Downloading channel metadata', 'Unable to download channel metadata',\n            query={'szBjId': broadcaster_id}, fatal=False), {dict}) or {}\n\n        return {\n            'id': broadcast_no,\n            'title': channel_info.get('TITLE') or station_info.get('station_title'),\n            'uploader': channel_info.get('BJNICK') or station_info.get('station_name'),\n            'uploader_id': broadcaster_id,\n            'timestamp': parse_iso8601(station_info.get('broad_start'), delimiter=' ', timezone=dt.timedelta(hours=9)),\n            'formats': formats,","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/yt-dlp/yt-dlp/blob/81ecd58b1394793e6da9998cc19fdb45657f1685/yt_dlp/extractor/afreecatv.py#L381-L417","documentation":"Soop live extractor: the access-token API (player_live_api.php with bno/stream_type/type/quality/pwd) returned CHANNEL without an AID and RESULT == 0 -- the broadcast number is valid but the stream is over. Expected error; the usual follow-up is a replay VOD that appears later.","triggerScenarios":"Joining a sooplive livestream in the minutes after it ended: the channel step still resolved a BNO, but the token step no longer issues an AID for it.","commonSituations":"Race at stream end; polling scripts hammering an ended broadcast; replays not yet uploaded so nothing to fall back to.","solutions":["Re-check the channel -- if the broadcaster restarted, a new BNO applies (re-run the original channel URL)","Wait for the replay VOD to be published on vod.sooplive.com and extract that instead","Treat as terminal for live extraction; do not retry the same BNO"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"from yt_dlp import YoutubeDL\nfrom yt_dlp.utils import DownloadError\n\ntry:\n    info = YoutubeDL().extract_info(live_url)          # play.sooplive.com/<bid>\nexcept DownloadError as e:\n    if 'This livestream has ended' in str(e):\n        # fall back: replay VODs surface on vod.sooplive.com; re-check later\n        info = try_replay_vod(broadcaster_id, delay_hours=1)\n    else:\n        raise","preventionTips":["Start recorders slightly before announced stream times to avoid the post-end race","On 'ended', poll the broadcaster's VOD list for the replay instead of the live URL"],"tags":["afreecatv","soop","live","ended"],"backgroundTag":"livestream-ended","analyzedSha":"81ecd58b1394793e6da9998cc19fdb45657f1685","analyzedAt":"2026-08-22T12:21:25.439Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}