gfycat.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. from .common import InfoExtractor
  4. from ..utils import (
  5. int_or_none,
  6. float_or_none,
  7. qualities,
  8. )
  9. class GfycatIE(InfoExtractor):
  10. _VALID_URL = r'https?://(?:www\.)?gfycat\.com/(?:ifr/)?(?P<id>[^/?#]+)'
  11. _TESTS = [{
  12. 'url': 'http://gfycat.com/DeadlyDecisiveGermanpinscher',
  13. 'info_dict': {
  14. 'id': 'DeadlyDecisiveGermanpinscher',
  15. 'ext': 'mp4',
  16. 'title': 'Ghost in the Shell',
  17. 'timestamp': 1410656006,
  18. 'upload_date': '20140914',
  19. 'uploader': 'anonymous',
  20. 'duration': 10.4,
  21. 'view_count': int,
  22. 'like_count': int,
  23. 'dislike_count': int,
  24. 'categories': list,
  25. 'age_limit': 0,
  26. }
  27. }, {
  28. 'url': 'http://gfycat.com/ifr/JauntyTimelyAmazontreeboa',
  29. 'info_dict': {
  30. 'id': 'JauntyTimelyAmazontreeboa',
  31. 'ext': 'mp4',
  32. 'title': 'JauntyTimelyAmazontreeboa',
  33. 'timestamp': 1411720126,
  34. 'upload_date': '20140926',
  35. 'uploader': 'anonymous',
  36. 'duration': 3.52,
  37. 'view_count': int,
  38. 'like_count': int,
  39. 'dislike_count': int,
  40. 'categories': list,
  41. 'age_limit': 0,
  42. }
  43. }]
  44. def _real_extract(self, url):
  45. video_id = self._match_id(url)
  46. gfy = self._download_json(
  47. 'http://gfycat.com/cajax/get/%s' % video_id,
  48. video_id, 'Downloading video info')['gfyItem']
  49. title = gfy.get('title') or gfy['gfyName']
  50. description = gfy.get('description')
  51. timestamp = int_or_none(gfy.get('createDate'))
  52. uploader = gfy.get('userName')
  53. view_count = int_or_none(gfy.get('views'))
  54. like_count = int_or_none(gfy.get('likes'))
  55. dislike_count = int_or_none(gfy.get('dislikes'))
  56. age_limit = 18 if gfy.get('nsfw') == '1' else 0
  57. width = int_or_none(gfy.get('width'))
  58. height = int_or_none(gfy.get('height'))
  59. fps = int_or_none(gfy.get('frameRate'))
  60. num_frames = int_or_none(gfy.get('numFrames'))
  61. duration = float_or_none(num_frames, fps) if num_frames and fps else None
  62. categories = gfy.get('tags') or gfy.get('extraLemmas') or []
  63. FORMATS = ('gif', 'webm', 'mp4')
  64. quality = qualities(FORMATS)
  65. formats = []
  66. for format_id in FORMATS:
  67. video_url = gfy.get('%sUrl' % format_id)
  68. if not video_url:
  69. continue
  70. filesize = gfy.get('%sSize' % format_id)
  71. formats.append({
  72. 'url': video_url,
  73. 'format_id': format_id,
  74. 'width': width,
  75. 'height': height,
  76. 'fps': fps,
  77. 'filesize': filesize,
  78. 'quality': quality(format_id),
  79. })
  80. self._sort_formats(formats)
  81. return {
  82. 'id': video_id,
  83. 'title': title,
  84. 'description': description,
  85. 'timestamp': timestamp,
  86. 'uploader': uploader,
  87. 'duration': duration,
  88. 'view_count': view_count,
  89. 'like_count': like_count,
  90. 'dislike_count': dislike_count,
  91. 'categories': categories,
  92. 'age_limit': age_limit,
  93. 'formats': formats,
  94. }