4 from .common
import InfoExtractor
5 from ..utils
import ExtractorError
, determine_ext
, unified_strdate
, url_or_none
6 from ..utils
.traversal
import traverse_obj
9 class ZenPornIE(InfoExtractor
):
10 _VALID_URL
= r
'https?://(?:www\.)?zenporn\.com/video/(?P<id>\d+)'
12 'url': 'https://zenporn.com/video/15627016/desi-bhabi-ki-chudai',
13 'md5': '07bd576b5920714d74975c054ca28dee',
16 'display_id': '15627016',
18 'title': 'md5:669eafd3bbc688aa29770553b738ada2',
20 'thumbnail': 'md5:2fc044a19bab450fef8f1931e7920a18',
21 'upload_date': '20230925',
22 'uploader': 'md5:9fae59847f1f58d1da8f2772016c12f3',
26 'url': 'https://zenporn.com/video/15570701',
27 'md5': 'acba0d080d692664fcc8c4e5502b1a67',
30 'display_id': '15570701',
32 'title': 'md5:47aebdf87644ec91e8b1a844bc832451',
34 'thumbnail': 'https://mstn.nv7s.com/contents/videos_screenshots/2297000/2297875/480x270/1.jpg',
35 'upload_date': '20230921',
36 'uploader': 'Lois Clarke',
40 'url': 'https://zenporn.com/video/8531117/amateur-students-having-a-fuck-fest-at-club/',
41 'md5': '67411256aa9451449e4d29f3be525541',
44 'display_id': '8531117',
46 'title': 'Amateur students having a fuck fest at club',
48 'thumbnail': 'https://tn.txxx.tube/contents/videos_screenshots/12791000/12791908/288x162/1.jpg',
49 'upload_date': '20191005',
50 'uploader': 'Jackopenass',
54 'url': 'https://zenporn.com/video/15872038/glad-you-came/',
55 'md5': '296ccab437f5bac6099433768449d8e1',
58 'display_id': '15872038',
60 'title': 'Glad You Came',
62 'thumbnail': 'https://vpim.m3pd.com/contents/videos_screenshots/111000/111585/480x270/1.jpg',
63 'upload_date': '20231024',
64 'uploader': 'Martin Rudenko',
69 def _gen_info_url(self
, ext_domain
, extr_id
, lifetime
=86400):
70 """ This function is a reverse engineering from the website javascript """
71 result
= '/'.join(str(int(extr_id
) // i
* i
) for i
in (1_000_000, 1_000, 1))
72 return f
'https://{ext_domain}/api/json/video/{lifetime}/{result}.json'
75 def _decode_video_url(encoded_url
):
76 """ This function is a reverse engineering from the website javascript """
77 # Replace lookalike characters and standardize map
78 translation
= str.maketrans('АВСЕМ.,~', 'ABCEM+/=')
80 return base64
.b64decode(encoded_url
.translate(translation
), validate
=True).decode()
81 except (binascii
.Error
, ValueError):
84 def _real_extract(self
, url
):
85 display_id
= self
._match
_id
(url
)
86 webpage
= self
._download
_webpage
(url
, display_id
)
88 ext_domain
, video_id
= self
._search
_regex
(
89 r
'https://(?P<ext_domain>[\w.-]+\.\w{3})/embed/(?P<extr_id>\d+)/',
90 webpage
, 'embed info', group
=('ext_domain', 'extr_id'))
92 info_json
= self
._download
_json
(
93 self
._gen
_info
_url
(ext_domain
, video_id
), video_id
, fatal
=False)
95 video_json
= self
._download
_json
(
96 f
'https://{ext_domain}/api/videofile.php', video_id
, query
={
99 }, note
='Downloading video file JSON', errnote
='Failed to download video file JSON')
101 decoded_url
= self
._decode
_video
_url
(video_json
[0]['video_url'])
103 raise ExtractorError('Unable to decode the video url')
107 'display_id': display_id
,
108 'ext': traverse_obj(video_json
, (0, 'format', {determine_ext}
)),
109 'url': f
'https://{ext_domain}{decoded_url}',
111 **traverse_obj(info_json
, ('video', {
112 'title': ('title', {str}
),
113 'description': ('description', {str}
),
114 'thumbnail': ('thumb', {url_or_none}
),
115 'upload_date': ('post_date', {unified_strdate}
),
116 'uploader': ('user', 'username', {str}
),