[rutv] Refactor vgtrk/rutv extractor
[youtube-dl] / youtube_dl / extractor / rutv.py
1 # encoding: utf-8
2 from __future__ import unicode_literals
3
4 import re
5
6 from .common import InfoExtractor
7 from ..utils import (
8     ExtractorError,
9     int_or_none
10 )
11
12
13 class RUTVIE(InfoExtractor):
14     IE_DESC = 'RUTV.RU'
15     _VALID_URL = r'https?://player\.(?:rutv\.ru|vgtrk\.com)/(?:flash2v/container\.swf\?id=|iframe/(?P<type>swf|video|live)/id/)(?P<id>\d+)'
16
17     _TESTS = [
18         {
19             'url': 'http://player.rutv.ru/flash2v/container.swf?id=774471&sid=kultura&fbv=true&isPlay=true&ssl=false&i=560&acc_video_id=episode_id/972347/video_id/978186/brand_id/31724',
20             'info_dict': {
21                 'id': '774471',
22                 'ext': 'mp4',
23                 'title': 'Монологи на все времена',
24                 'description': 'md5:18d8b5e6a41fb1faa53819471852d5d5',
25                 'duration': 2906,
26             },
27             'params': {
28                 # m3u8 download
29                 'skip_download': True,
30             },
31         },
32         {
33             'url': 'https://player.vgtrk.com/flash2v/container.swf?id=774016&sid=russiatv&fbv=true&isPlay=true&ssl=false&i=560&acc_video_id=episode_id/972098/video_id/977760/brand_id/57638',
34             'info_dict': {
35                 'id': '774016',
36                 'ext': 'mp4',
37                 'title': 'Чужой в семье Сталина',
38                 'description': '',
39                 'duration': 2539,
40             },
41             'params': {
42                 # m3u8 download
43                 'skip_download': True,
44             },
45         },
46         {
47             'url': 'http://player.rutv.ru/iframe/swf/id/766888/sid/hitech/?acc_video_id=4000',
48             'info_dict': {
49                 'id': '766888',
50                 'ext': 'mp4',
51                 'title': 'Вести.net: интернет-гиганты начали перетягивание программных "одеял"',
52                 'description': 'md5:65ddd47f9830c4f42ed6475f8730c995',
53                 'duration': 279,
54             },
55             'params': {
56                 # m3u8 download
57                 'skip_download': True,
58             },
59         },
60         {
61             'url': 'http://player.rutv.ru/iframe/video/id/771852/start_zoom/true/showZoomBtn/false/sid/russiatv/?acc_video_id=episode_id/970443/video_id/975648/brand_id/5169',
62             'info_dict': {
63                 'id': '771852',
64                 'ext': 'mp4',
65                 'title': 'Прямой эфир. Жертвы загадочной болезни: смерть от старости в 17 лет',
66                 'description': 'md5:b81c8c55247a4bd996b43ce17395b2d8',
67                 'duration': 3096,
68             },
69             'params': {
70                 # m3u8 download
71                 'skip_download': True,
72             },
73         },
74         {
75             'url': 'http://player.rutv.ru/iframe/live/id/51499/showZoomBtn/false/isPlay/true/sid/sochi2014',
76             'info_dict': {
77                 'id': '51499',
78                 'ext': 'flv',
79                 'title': 'Сочи-2014. Биатлон. Индивидуальная гонка. Мужчины ',
80                 'description': 'md5:9e0ed5c9d2fa1efbfdfed90c9a6d179c',
81             },
82             'params': {
83                 # rtmp download
84                 'skip_download': True,
85             },
86             'skip': 'Translation has finished',
87         },
88     ]
89
90     @classmethod
91     def _extract_url(cls, webpage):
92         mobj = re.search(
93             r'<iframe[^>]+?src=(["\'])(?P<url>https?://player\.rutv\.ru/iframe/(?:swf|video|live)/id/.+?)\1', webpage)
94         if mobj:
95             return mobj.group('url')
96
97         mobj = re.search(
98             r'<meta[^>]+?property=(["\'])og:video\1[^>]+?content=(["\'])(?P<url>http://player\.(?:rutv\.ru|vgtrk\.com)/flash2v/container\.swf\?id=.+?\2)',
99             webpage)
100         if mobj:
101             return mobj.group('url')
102
103     def _real_extract(self, url):
104         mobj = re.match(self._VALID_URL, url)
105         video_id = mobj.group('id')
106         video_type = mobj.group('type')
107
108         if not video_type or video_type == 'swf':
109             video_type = 'video'
110
111         json_data = self._download_json(
112             'http://player.rutv.ru/iframe/%splay/id/%s' % ('live-' if video_type == 'live' else '', video_id),
113             video_id, 'Downloading JSON')
114
115         if json_data['errors']:
116             raise ExtractorError('%s said: %s' % (self.IE_NAME, json_data['errors']), expected=True)
117
118         playlist = json_data['data']['playlist']
119         medialist = playlist['medialist']
120         media = medialist[0]
121
122         if media['errors']:
123             raise ExtractorError('%s said: %s' % (self.IE_NAME, media['errors']), expected=True)
124
125         view_count = playlist.get('count_views')
126         priority_transport = playlist['priority_transport']
127
128         thumbnail = media['picture']
129         width = int_or_none(media['width'])
130         height = int_or_none(media['height'])
131         description = media['anons']
132         title = media['title']
133         duration = int_or_none(media.get('duration'))
134
135         formats = []
136
137         for transport, links in media['sources'].items():
138             for quality, url in links.items():
139                 if transport == 'rtmp':
140                     mobj = re.search(r'^(?P<url>rtmp://[^/]+/(?P<app>.+))/(?P<playpath>.+)$', url)
141                     if not mobj:
142                         continue
143                     fmt = {
144                         'url': mobj.group('url'),
145                         'play_path': mobj.group('playpath'),
146                         'app': mobj.group('app'),
147                         'page_url': 'http://player.rutv.ru',
148                         'player_url': 'http://player.rutv.ru/flash2v/osmf.swf?i=22',
149                         'rtmp_live': True,
150                         'ext': 'flv',
151                         'vbr': int(quality),
152                     }
153                 elif transport == 'm3u8':
154                     fmt = {
155                         'url': url,
156                         'ext': 'mp4',
157                     }
158                 else:
159                     fmt = {
160                         'url': url
161                     }
162                 fmt.update({
163                     'width': width,
164                     'height': height,
165                     'format_id': '%s-%s' % (transport, quality),
166                     'preference': -1 if priority_transport == transport else -2,
167                 })
168                 formats.append(fmt)
169
170         if not formats:
171             raise ExtractorError('No media links available for %s' % video_id)
172
173         self._sort_formats(formats)
174
175         return {
176             'id': video_id,
177             'title': title,
178             'description': description,
179             'thumbnail': thumbnail,
180             'view_count': view_count,
181             'duration': duration,
182             'formats': formats,
183         }