1 from .common
import InfoExtractor
10 class GfycatIE(InfoExtractor
):
11 _VALID_URL
= r
'https?://(?:(?:www|giant|thumbs)\.)?gfycat\.com/(?i:ru/|ifr/|gifs/detail/)?(?P<id>[^-/?#\."\']+)'
12 _EMBED_REGEX = [rf'<(?
:iframe|source
)[^
>]+\bsrc
=["\'](?P<url>{_VALID_URL})']
14 'url': 'http://gfycat.com/DeadlyDecisiveGermanpinscher',
16 'id': 'DeadlyDecisiveGermanpinscher',
18 'title': 'Ghost in the Shell',
19 'timestamp': 1410656006,
20 'upload_date': '20140914',
21 'uploader': 'anonymous',
27 'uploader_id': 'anonymous',
31 'url': 'http://gfycat.com/ifr/JauntyTimelyAmazontreeboa',
33 'id': 'JauntyTimelyAmazontreeboa',
35 'title': 'JauntyTimelyAmazontreeboa',
36 'timestamp': 1411720126,
37 'upload_date': '20140926',
38 'uploader': 'anonymous',
44 'uploader_id': 'anonymous',
48 'url': 'https://gfycat.com/alienatedsolidgreathornedowl',
50 'id': 'alienatedsolidgreathornedowl',
52 'upload_date': '20211226',
53 'uploader_id': 'reactions',
54 'timestamp': 1640536930,
57 'title': 'Ingrid Michaelson, Zooey Deschanel - Merry Christmas Happy New Year',
60 'duration': 2.9583333333333335,
61 'uploader': 'Reaction GIFs',
65 'url': 'https://gfycat.com/ru/RemarkableDrearyAmurstarfish',
68 'url': 'https://gfycat.com/gifs/detail/UnconsciousLankyIvorygull',
71 'url': 'https://gfycat.com/acceptablehappygoluckyharborporpoise-baseball',
74 'url': 'https://thumbs.gfycat.com/acceptablehappygoluckyharborporpoise-size_restricted.gif',
77 'url': 'https://giant.gfycat.com/acceptablehappygoluckyharborporpoise.mp4',
80 'url': 'http://gfycat.com/IFR/JauntyTimelyAmazontreeboa',
84 def _real_extract(self, url):
85 video_id = self._match_id(url)
87 gfy = self._download_json(
88 'https://api.gfycat.com/v1/gfycats/%s' % video_id,
89 video_id, 'Downloading video info')
91 raise ExtractorError('Gfycat said: ' + gfy['error'], expected=True)
94 title = gfy.get('title') or gfy['gfyName']
95 description = gfy.get('description')
96 timestamp = int_or_none(gfy.get('createDate'))
97 uploader = gfy.get('userName') or gfy.get('username')
98 view_count = int_or_none(gfy.get('views'))
99 like_count = int_or_none(gfy.get('likes'))
100 dislike_count = int_or_none(gfy.get('dislikes'))
101 age_limit = 18 if gfy.get('nsfw') == '1' else 0
103 width = int_or_none(gfy.get('width'))
104 height = int_or_none(gfy.get('height'))
105 fps = int_or_none(gfy.get('frameRate'))
106 num_frames = int_or_none(gfy.get('numFrames'))
108 duration = float_or_none(num_frames, fps) if num_frames and fps else None
110 categories = gfy.get('tags') or gfy.get('extraLemmas') or []
112 FORMATS = ('gif', 'webm', 'mp4')
113 quality = qualities(FORMATS)
116 for format_id in FORMATS:
117 video_url = gfy.get('%sUrl' % format_id)
120 filesize = int_or_none(gfy.get('%sSize' % format_id))
123 'format_id': format_id,
127 'filesize': filesize,
128 'quality': quality(format_id),
134 'description': description,
135 'timestamp': timestamp,
136 'uploader': gfy.get('userDisplayName') or uploader,
137 'uploader_id': uploader,
138 'duration': duration,
139 'view_count': view_count,
140 'like_count': like_count,
141 'dislike_count': dislike_count,
142 'categories': categories,
143 'age_limit': age_limit,