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