]>
Commit | Line | Data |
---|---|---|
1 | from .common import InfoExtractor | |
2 | from ..utils import ( | |
3 | OnDemandPagedList, | |
4 | int_or_none, | |
5 | traverse_obj, | |
6 | unified_timestamp, | |
7 | url_or_none, | |
8 | ) | |
9 | ||
10 | ||
11 | class YappyIE(InfoExtractor): | |
12 | _WORKING = False | |
13 | _VALID_URL = r'https?://yappy\.media/video/(?P<id>\w+)' | |
14 | _TESTS = [{ | |
15 | 'url': 'https://yappy.media/video/47fea6d8586f48d1a0cf96a7342aabd2', | |
16 | 'info_dict': { | |
17 | 'id': '47fea6d8586f48d1a0cf96a7342aabd2', | |
18 | 'ext': 'mp4', | |
19 | 'title': 'Куда нажимать? Как снимать? Смотри видос и погнали!🤘🏻', | |
20 | 'timestamp': 1661893200, | |
21 | 'description': 'Куда нажимать? Как снимать? Смотри видос и погнали!🤘🏻', | |
22 | 'thumbnail': 'https://cdn-st.ritm.media/static/pic/thumbnails/0c7c4d73388f47848acaf540d2e2bb8c-thumbnail.jpg', | |
23 | 'upload_date': '20220830', | |
24 | 'view_count': int, | |
25 | 'like_count': int, | |
26 | 'uploader_id': '59a0c8c485e5410b9c43474bf4c6a373', | |
27 | 'categories': ['Образование и наука', 'Лайфхак', 'Технологии', 'Арт/искусство'], | |
28 | 'repost_count': int, | |
29 | 'uploader': 'YAPPY', | |
30 | } | |
31 | }, { | |
32 | 'url': 'https://yappy.media/video/3862451954ad4bd58ae2ccefddb0bd33', | |
33 | 'info_dict': { | |
34 | 'id': '3862451954ad4bd58ae2ccefddb0bd33', | |
35 | 'ext': 'mp4', | |
36 | 'title': 'Опиши свой характер 3 словами🙃\n#психология #дружба #отношения', | |
37 | 'timestamp': 1674726985, | |
38 | 'like_count': int, | |
39 | 'description': 'Опиши свой характер 3 словами🙃\n#психология #дружба #отношения', | |
40 | 'uploader_id': '6793ee3581974a3586fc01e157de6c99', | |
41 | 'view_count': int, | |
42 | 'repost_count': int, | |
43 | 'uploader': 'LENA SHTURMAN', | |
44 | 'upload_date': '20230126', | |
45 | 'thumbnail': 'https://cdn-st.ritm.media/static/pic/user_thumbnails/6e76bb4bbad640b6/9ec84c115b2b1967/1674716171.jpg', | |
46 | } | |
47 | }] | |
48 | ||
49 | def _real_extract(self, url): | |
50 | video_id = self._match_id(url) | |
51 | webpage = self._download_webpage(url, video_id) | |
52 | json_ld = self._search_json_ld(webpage, video_id) | |
53 | nextjs_data = self._search_nextjs_data(webpage, video_id) | |
54 | ||
55 | media_data = ( | |
56 | traverse_obj( | |
57 | nextjs_data, ('props', 'pageProps', ('data', 'OpenGraphParameters')), get_all=False) | |
58 | or self._download_json(f'https://yappy.media/api/video/{video_id}', video_id)) | |
59 | ||
60 | media_url = traverse_obj(media_data, ('link', {url_or_none})) or '' | |
61 | has_watermark = media_url.endswith('-wm.mp4') | |
62 | ||
63 | formats = [{ | |
64 | 'url': media_url, | |
65 | 'ext': 'mp4', | |
66 | 'format_note': 'Watermarked' if has_watermark else None, | |
67 | 'preference': -10 if has_watermark else None | |
68 | }] if media_url else [] | |
69 | ||
70 | if has_watermark: | |
71 | formats.append({ | |
72 | 'url': media_url.replace('-wm.mp4', '.mp4'), | |
73 | 'ext': 'mp4' | |
74 | }) | |
75 | ||
76 | audio_link = traverse_obj(media_data, ('audio', 'link')) | |
77 | if audio_link: | |
78 | formats.append({ | |
79 | 'url': audio_link, | |
80 | 'ext': 'mp3', | |
81 | 'acodec': 'mp3', | |
82 | 'vcodec': 'none' | |
83 | }) | |
84 | ||
85 | return { | |
86 | 'id': video_id, | |
87 | 'title': (json_ld.get('description') or self._html_search_meta(['og:title'], webpage) | |
88 | or self._html_extract_title(webpage)), | |
89 | 'formats': formats, | |
90 | 'thumbnail': (media_data.get('thumbnail') | |
91 | or self._html_search_meta(['og:image', 'og:image:secure_url'], webpage)), | |
92 | 'description': (media_data.get('description') or json_ld.get('description') | |
93 | or self._html_search_meta(['description', 'og:description'], webpage)), | |
94 | 'timestamp': unified_timestamp(media_data.get('publishedAt') or json_ld.get('timestamp')), | |
95 | 'view_count': int_or_none(media_data.get('viewsCount') or json_ld.get('view_count')), | |
96 | 'like_count': int_or_none(media_data.get('likesCount')), | |
97 | 'uploader': traverse_obj(media_data, ('creator', 'firstName')), | |
98 | 'uploader_id': traverse_obj(media_data, ('creator', ('uuid', 'nickname')), get_all=False), | |
99 | 'categories': traverse_obj(media_data, ('categories', ..., 'name')) or None, | |
100 | 'repost_count': int_or_none(media_data.get('sharingCount')) | |
101 | } | |
102 | ||
103 | ||
104 | class YappyProfileIE(InfoExtractor): | |
105 | _VALID_URL = r'https?://yappy\.media/profile/(?P<id>\w+)' | |
106 | _TESTS = [{ | |
107 | 'url': 'https://yappy.media/profile/59a0c8c485e5410b9c43474bf4c6a373', | |
108 | 'info_dict': { | |
109 | 'id': '59a0c8c485e5410b9c43474bf4c6a373', | |
110 | }, | |
111 | 'playlist_mincount': 527, | |
112 | }] | |
113 | ||
114 | def _real_extract(self, url): | |
115 | profile_id = self._match_id(url) | |
116 | ||
117 | def fetch_page(page_num): | |
118 | page_num += 1 | |
119 | videos = self._download_json( | |
120 | f'https://yappy.media/api/video/list/{profile_id}?page={page_num}', | |
121 | profile_id, f'Downloading profile page {page_num} JSON') | |
122 | ||
123 | for video in traverse_obj(videos, ('results', lambda _, v: v['uuid'])): | |
124 | yield self.url_result( | |
125 | f'https://yappy.media/video/{video["uuid"]}', YappyIE, | |
126 | video['uuid'], video.get('description')) | |
127 | ||
128 | return self.playlist_result(OnDemandPagedList(fetch_page, 15), profile_id) |