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

Code before:
    def _add_quality_formats(self, formats, quality_meta):
        vcodec = traverse_obj(quality_meta, ('vcodec', 0, {str}))
        quality = traverse_obj(quality_meta, ('now_quality', 0, {str}))
        quality_priority = qualities(('low', 'h264', 'high'))(quality)
        if traverse_obj(quality_meta, ('hlsaddr', 0, {url_or_none})):
            formats.append({
                'format_id': quality,
                'url': quality_meta['hlsaddr'][0],
                'ext': 'mp4',
                'vcodec': vcodec,
                'quality': quality_priority,
            })
        if traverse_obj(quality_meta, ('hlsaddr_audioonly', 0, {url_or_none})):
            formats.append({
                'format_id': join_nonempty(quality, 'audioonly'),
                'url': quality_meta['hlsaddr_audioonly'][0],
                'ext': 'm4a',
                'vcodec': 'none',
                'quality': quality_priority,
            })

    def _real_extract(self, url):
        video_id = self._match_id(url)
        html = self._download_webpage(url, video_id)

        if 'タイムシフトが見つかりませんでした。' in html:
            raise ExtractorError('This stream has expired', expected=True)

        title = clean_html(
            get_element_by_id('livetitle', html.replace('<SPAN', '<span').replace('SPAN>', 'span>')))
        description = self._html_search_meta('Description', html)
        thumbnail = self._html_search_meta(['og:image', 'twitter:image'], html)

        if self._search_regex(r'(var\s+timeshift\s*=\s*false)', html, 'is livestream', default=False):
            formats = []
            for (desc, code) in [('high', 'Z'), ('low', 'ForceLow')]:
                quality_meta = self._get_quality_meta(video_id, desc, code)
                self._add_quality_formats(formats, quality_meta)
                if desc == 'high' and traverse_obj(quality_meta, ('vcodec', 0)) == 'HEVC':
                    self._add_quality_formats(
                        formats, self._get_quality_meta(video_id, desc, code, force_h264='1'))

            return {
                'id': video_id,
                'title': title,
                'description': description,
                'thumbnail': thumbnail,
                'is_live': True,
                'formats': formats,
            }


Review comment (suggestion):
make sure this isn't added by a user
```suggestion
        if '>タイムシフトが見つかりませんでした。<' in html:
```

Code after:
    def _add_quality_formats(self, formats, quality_meta):
        vcodec = traverse_obj(quality_meta, ('vcodec', 0, {str}))
        quality = traverse_obj(quality_meta, ('now_quality', 0, {str}))
        quality_priority = qualities(('low', 'h264', 'high'))(quality)
        if traverse_obj(quality_meta, ('hlsaddr', 0, {url_or_none})):
            formats.append({
                'format_id': quality,
                'url': quality_meta['hlsaddr'][0],
                'ext': 'mp4',
                'vcodec': vcodec,
                'quality': quality_priority,
            })
        if traverse_obj(quality_meta, ('hlsaddr_audioonly', 0, {url_or_none})):
            formats.append({
                'format_id': join_nonempty(quality, 'audioonly'),
                'url': quality_meta['hlsaddr_audioonly'][0],
                'ext': 'm4a',
                'vcodec': 'none',
                'quality': quality_priority,
            })

    def _real_extract(self, url):
        video_id = self._match_id(url)
        html = self._download_webpage(url, video_id)

        if '>タイムシフトが見つかりませんでした。<' in html:
            raise ExtractorError('This stream has expired', expected=True)

        title = clean_html(
            get_element_by_id('livetitle', html.replace('<SPAN', '<span').replace('SPAN>', 'span>')))
        description = self._html_search_meta('Description', html)
        thumbnail = self._html_search_meta(['og:image', 'twitter:image'], html)

        if self._search_regex(r'(var\s+timeshift\s*=\s*false)', html, 'is livestream', default=False):
            formats = []
            for (desc, code) in [('high', 'Z'), ('low', 'ForceLow')]:
                quality_meta = self._get_quality_meta(video_id, desc, code)
                self._add_quality_formats(formats, quality_meta)
                if desc == 'high' and traverse_obj(quality_meta, ('vcodec', 0)) == 'HEVC':
                    self._add_quality_formats(
                        formats, self._get_quality_meta(video_id, desc, code, force_h264='1'))

            return {
                'id': video_id,
                'title': title,
                'description': description,
                'thumbnail': thumbnail,
                'is_live': True,
                'formats': formats,
            }