3 from .common
import InfoExtractor
11 class ChaturbateIE(InfoExtractor
):
12 _VALID_URL
= r
'https?://(?:[^/]+\.)?chaturbate\.com/(?:fullvideo/?\?.*?\bb=)?(?P<id>[^/?&#]+)'
14 'url': 'https://www.chaturbate.com/siswet19/',
18 'title': 're:^siswet19 [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$',
23 'skip_download': True,
25 'skip': 'Room is offline',
27 'url': 'https://chaturbate.com/fullvideo/?b=caylin',
28 'only_matching': True,
30 'url': 'https://en.chaturbate.com/siswet19/',
31 'only_matching': True,
34 _ROOM_OFFLINE
= 'Room is currently offline'
36 def _real_extract(self
, url
):
37 video_id
= self
._match
_id
(url
)
39 webpage
= self
._download
_webpage
(
40 f
'https://chaturbate.com/{video_id}/', video_id
,
41 headers
=self
.geo_verification_headers())
45 data
= self
._parse
_json
(
47 r
'initialRoomDossier\s*=\s*(["\'])(?P
<value
>(?
:(?
!\
1).)+)\
1',
48 webpage, 'data
', default='{}', group='value
'),
49 video_id, transform_source=lowercase_escape, fatal=False)
51 m3u8_url = url_or_none(data.get('hls_source
'))
53 found_m3u8_urls.append(m3u8_url)
55 if not found_m3u8_urls:
57 r'(\\u002
[27])(?P
<url
>http
.+?\
.m3u8
.*?
)\
1', webpage):
58 found_m3u8_urls.append(lowercase_escape(m.group('url
')))
60 if not found_m3u8_urls:
62 r'(["\'])(?P<url>http.+?\.m3u8.*?)\1', webpage):
63 found_m3u8_urls.append(m.group('url'))
66 for found_m3u8_url in found_m3u8_urls:
67 m3u8_fast_url, m3u8_no_fast_url = found_m3u8_url, found_m3u8_url.replace('_fast', '')
68 for m3u8_url in (m3u8_fast_url, m3u8_no_fast_url):
69 if m3u8_url not in m3u8_urls:
70 m3u8_urls.append(m3u8_url)
73 error = self._search_regex(
74 [r'<span[^>]+class=(["\'])desc_span\
1[^
>]*>(?P
<error
>[^
<]+)</span
>',
75 r'<div
[^
>]+id=(["\'])defchat\1[^>]*>\s*<p><strong>(?P<error>[^<]+)<'],
76 webpage, 'error', group='error', default=None)
78 if any(p in webpage for p in (
79 self._ROOM_OFFLINE, 'offline_tipping', 'tip_offline')):
80 error = self._ROOM_OFFLINE
82 raise ExtractorError(error, expected=True)
83 raise ExtractorError('Unable to find stream URL')
86 for m3u8_url in m3u8_urls:
87 for known_id in ('fast', 'slow'):
88 if f'_{known_id}' in m3u8_url:
93 formats.extend(self._extract_m3u8_formats(
94 m3u8_url, video_id, ext='mp4',
95 # ffmpeg skips segments for fast m3u8
96 preference=-10 if m3u8_id == 'fast' else None,
97 m3u8_id=m3u8_id, fatal=False, live=True))
102 'thumbnail': f'https://roomimg.stream.highwebmedia.com/ri/{video_id}.jpg',
103 'age_limit': self._rta_search(webpage),