streamable.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. from .common import InfoExtractor
  4. from ..utils import (
  5. ExtractorError,
  6. float_or_none
  7. )
  8. class StreamableIE(InfoExtractor):
  9. _VALID_URL = r'https?://streamable\.com/(?P<id>[\w]+)'
  10. _TESTS = [
  11. {
  12. 'url': 'https://streamable.com/dnd1',
  13. 'md5': '3e3bc5ca088b48c2d436529b64397fef',
  14. 'info_dict': {
  15. 'id': 'dnd1',
  16. 'ext': 'mp4',
  17. 'title': 'Mikel Oiarzabal scores to make it 0-3 for La Real against Espanyol',
  18. 'thumbnail': 'http://cdn.streamable.com/image/dnd1.jpg',
  19. }
  20. },
  21. # older video without bitrate, width/height, etc. info
  22. {
  23. 'url': 'https://streamable.com/moo',
  24. 'md5': '2cf6923639b87fba3279ad0df3a64e73',
  25. 'info_dict': {
  26. 'id': 'moo',
  27. 'ext': 'mp4',
  28. 'title': '"Please don\'t eat me!"',
  29. 'thumbnail': 'http://cdn.streamable.com/image/f6441ae0c84311e4af010bc47400a0a4.jpg',
  30. }
  31. }
  32. ]
  33. def _real_extract(self, url):
  34. video_id = self._match_id(url)
  35. # Note: Using the ajax API, as the public Streamable API doesn't seem
  36. # to return video info like the title properly sometimes, and doesn't
  37. # include info like the video duration
  38. video = self._download_json(
  39. 'https://streamable.com/ajax/videos/%s' % video_id, video_id)
  40. # Format IDs:
  41. # 0 The video is being uploaded
  42. # 1 The video is being processed
  43. # 2 The video has at least one file ready
  44. # 3 The video is unavailable due to an error
  45. status = video.get('status')
  46. if status != 2:
  47. raise ExtractorError(
  48. 'This video is currently unavailable. It may still be uploading or processing.',
  49. expected=True)
  50. formats = []
  51. for key, info in video.get('files').items():
  52. formats.append({
  53. 'format_id': key,
  54. 'url': info['url'],
  55. 'width': info.get('width'),
  56. 'height': info.get('height'),
  57. 'filesize': info.get('size'),
  58. 'fps': info.get('framerate'),
  59. 'vbr': float_or_none(info.get('bitrate'), 1000)
  60. })
  61. self._sort_formats(formats)
  62. return {
  63. 'id': video_id,
  64. 'title': video.get('result_title'),
  65. 'thumbnail': video.get('thumbnail_url'),
  66. 'duration': video.get('duration'),
  67. 'formats': formats
  68. }