release 2017.04.16
[youtube-dl] / youtube_dl / extractor / go90.py
1 # coding: utf-8
2 from __future__ import unicode_literals
3
4 import re
5
6 from .common import InfoExtractor
7 from ..utils import (
8     int_or_none,
9     parse_iso8601,
10 )
11
12
13 class Go90IE(InfoExtractor):
14     _VALID_URL = r'https?://(?:www\.)?go90\.com/videos/(?P<id>[0-9a-zA-Z]+)'
15     _TEST = {
16         'url': 'https://www.go90.com/videos/84BUqjLpf9D',
17         'md5': 'efa7670dbbbf21a7b07b360652b24a32',
18         'info_dict': {
19             'id': '84BUqjLpf9D',
20             'ext': 'mp4',
21             'title': 'Inside The Utah Coalition Against Pornography Convention',
22             'description': 'VICE\'s Karley Sciortino meets with activists who discuss the state\'s strong anti-porn stance. Then, VICE Sports explains NFL contracts.',
23             'timestamp': 1491868800,
24             'upload_date': '20170411',
25         }
26     }
27
28     def _real_extract(self, url):
29         video_id = self._match_id(url)
30         video_data = self._download_json(
31             'https://www.go90.com/api/view/items/' + video_id,
32             video_id, headers={
33                 'Content-Type': 'application/json; charset=utf-8',
34             }, data=b'{"client":"web","device_type":"pc"}')
35         title = video_data['title']
36         main_video_asset = video_data['main_video_asset']
37
38         thumbnails = []
39         formats = []
40         for asset in video_data.get('assets'):
41             if asset.get('id') == main_video_asset:
42                 for source in asset.get('sources', []):
43                     source_location = source.get('location')
44                     if not source_location:
45                         continue
46                     source_type = source.get('type')
47                     if source_type == 'hls':
48                         m3u8_formats = self._extract_m3u8_formats(
49                             source_location, video_id, 'mp4',
50                             'm3u8_native', m3u8_id='hls', fatal=False)
51                         for f in m3u8_formats:
52                             mobj = re.search(r'/hls-(\d+)-(\d+)K', f['url'])
53                             if mobj:
54                                 height, tbr = mobj.groups()
55                                 height = int_or_none(height)
56                                 f.update({
57                                     'height': f.get('height') or height,
58                                     'width': f.get('width') or int_or_none(height / 9.0 * 16.0 if height else None),
59                                     'tbr': f.get('tbr') or int_or_none(tbr),
60                                 })
61                         formats.extend(m3u8_formats)
62                     elif source_type == 'dash':
63                         formats.extend(self._extract_mpd_formats(
64                             source_location, video_id, mpd_id='dash', fatal=False))
65                     else:
66                         formats.append({
67                             'format_id': source.get('name'),
68                             'url': source_location,
69                             'width': int_or_none(source.get('width')),
70                             'height': int_or_none(source.get('height')),
71                             'tbr': int_or_none(source.get('bitrate')),
72                         })
73             elif asset.get('type') == 'image':
74                 asset_location = asset.get('location')
75                 if not asset_location:
76                     continue
77                 thumbnails.append({
78                     'url': asset_location,
79                     'width': int_or_none(asset.get('width')),
80                     'height': int_or_none(asset.get('height')),
81                 })
82         self._sort_formats(formats)
83
84         return {
85             'id': video_id,
86             'title': title,
87             'formats': formats,
88             'thumbnails': thumbnails,
89             'description': video_data.get('short_description'),
90             'like_count': int_or_none(video_data.get('like_count')),
91             'timestamp': parse_iso8601(video_data.get('released_at')),
92         }