2 from __future__ import unicode_literals
4 from .common import InfoExtractor
11 class StreamableIE(InfoExtractor):
12 _VALID_URL = r'https?://streamable\.com/(?P<id>[\w]+)'
15 'url': 'https://streamable.com/dnd1',
16 'md5': '3e3bc5ca088b48c2d436529b64397fef',
20 'title': 'Mikel Oiarzabal scores to make it 0-3 for La Real against Espanyol',
21 'thumbnail': 'http://cdn.streamable.com/image/dnd1.jpg',
24 # older video without bitrate, width/height, etc. info
26 'url': 'https://streamable.com/moo',
27 'md5': '2cf6923639b87fba3279ad0df3a64e73',
31 'title': '"Please don\'t eat me!"',
32 'thumbnail': 'http://cdn.streamable.com/image/f6441ae0c84311e4af010bc47400a0a4.jpg',
37 def _real_extract(self, url):
38 video_id = self._match_id(url)
40 # Note: Using the ajax API, as the public Streamable API doesn't seem
41 # to return video info like the title properly sometimes, and doesn't
42 # include info like the video duration
43 video = self._download_json(
44 'https://streamable.com/ajax/videos/%s' % video_id, video_id)
47 # 0 The video is being uploaded
48 # 1 The video is being processed
49 # 2 The video has at least one file ready
50 # 3 The video is unavailable due to an error
51 status = video.get('status')
54 'This video is currently unavailable. It may still be uploading or processing.',
58 for key, info in video.get('files').items():
62 'width': info.get('width'),
63 'height': info.get('height'),
64 'filesize': info.get('size'),
65 'fps': info.get('framerate'),
66 'vbr': float_or_none(info.get('bitrate'), 1000)
68 self._sort_formats(formats)
72 'title': video.get('result_title'),
73 'thumbnail': video.get('thumbnail_url'),
74 'duration': video.get('duration'),