]>
Commit | Line | Data |
---|---|---|
fb8b8fdd S |
1 | # encoding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
7f2a9f1b S |
4 | import re |
5 | ||
fb8b8fdd S |
6 | from .common import InfoExtractor |
7 | from ..utils import ( | |
15b74b94 | 8 | ExtractorError, |
884ae747 | 9 | float_or_none, |
eb47569f | 10 | int_or_none, |
819039ee | 11 | parse_age_limit, |
fb8b8fdd S |
12 | ) |
13 | ||
14 | ||
15 | class TvigleIE(InfoExtractor): | |
16 | IE_NAME = 'tvigle' | |
17 | IE_DESC = 'Интернет-телевидение Tvigle.ru' | |
7f2a9f1b | 18 | _VALID_URL = r'https?://(?:www\.)?(?:tvigle\.ru/(?:[^/]+/)+(?P<display_id>[^/]+)/$|cloud\.tvigle\.ru/video/(?P<id>\d+))' |
c7095dad S |
19 | |
20 | _TESTS = [ | |
21 | { | |
819039ee S |
22 | 'url': 'http://www.tvigle.ru/video/sokrat/', |
23 | 'md5': '36514aed3657d4f70b4b2cef8eb520cd', | |
c7095dad | 24 | 'info_dict': { |
819039ee S |
25 | 'id': '1848932', |
26 | 'display_id': 'sokrat', | |
27 | 'ext': 'flv', | |
28 | 'title': 'Сократ', | |
eb47569f | 29 | 'description': 'md5:d6b92ffb7217b4b8ebad2e7665253c17', |
819039ee | 30 | 'duration': 6586, |
eb47569f | 31 | 'age_limit': 12, |
c7095dad | 32 | }, |
3153a2c9 | 33 | 'skip': 'georestricted', |
c7095dad S |
34 | }, |
35 | { | |
884ae747 | 36 | 'url': 'http://www.tvigle.ru/video/vladimir-vysotskii/vedushchii-teleprogrammy-60-minut-ssha-o-vladimire-vysotskom/', |
eb47569f | 37 | 'md5': 'e7efe5350dd5011d0de6550b53c3ba7b', |
c7095dad | 38 | 'info_dict': { |
884ae747 | 39 | 'id': '5142516', |
eb47569f | 40 | 'ext': 'flv', |
c7095dad S |
41 | 'title': 'Ведущий телепрограммы «60 минут» (США) о Владимире Высоцком', |
42 | 'description': 'md5:027f7dc872948f14c96d19b4178428a4', | |
884ae747 S |
43 | 'duration': 186.080, |
44 | 'age_limit': 0, | |
c7095dad | 45 | }, |
3153a2c9 | 46 | 'skip': 'georestricted', |
7f2a9f1b S |
47 | }, { |
48 | 'url': 'https://cloud.tvigle.ru/video/5267604/', | |
49 | 'only_matching': True, | |
50 | } | |
c7095dad | 51 | ] |
fb8b8fdd S |
52 | |
53 | def _real_extract(self, url): | |
7f2a9f1b S |
54 | mobj = re.match(self._VALID_URL, url) |
55 | video_id = mobj.group('id') | |
56 | display_id = mobj.group('display_id') | |
fb8b8fdd | 57 | |
7f2a9f1b S |
58 | if not video_id: |
59 | webpage = self._download_webpage(url, display_id) | |
60 | video_id = self._html_search_regex( | |
12a51345 S |
61 | (r'<div[^>]+class=["\']player["\'][^>]+id=["\'](\d+)', |
62 | r'var\s+cloudId\s*=\s*["\'](\d+)', | |
63 | r'class="video-preview current_playing" id="(\d+)"'), | |
7f2a9f1b | 64 | webpage, 'video id') |
fb8b8fdd | 65 | |
884ae747 S |
66 | video_data = self._download_json( |
67 | 'http://cloud.tvigle.ru/api/play/video/%s/' % video_id, display_id) | |
fb8b8fdd | 68 | |
884ae747 S |
69 | item = video_data['playlist']['items'][0] |
70 | ||
15b74b94 S |
71 | videos = item.get('videos') |
72 | ||
73 | error_message = item.get('errorMessage') | |
74 | if not videos and error_message: | |
75 | raise ExtractorError( | |
76 | '%s returned error: %s' % (self.IE_NAME, error_message), expected=True) | |
77 | ||
884ae747 | 78 | title = item['title'] |
7584e38c S |
79 | description = item.get('description') |
80 | thumbnail = item.get('thumbnail') | |
819039ee S |
81 | duration = float_or_none(item.get('durationMilliseconds'), 1000) |
82 | age_limit = parse_age_limit(item.get('ageRestrictions')) | |
fb8b8fdd | 83 | |
884ae747 S |
84 | formats = [] |
85 | for vcodec, fmts in item['videos'].items(): | |
1988647d S |
86 | if vcodec == 'hls': |
87 | continue | |
eb47569f S |
88 | for format_id, video_url in fmts.items(): |
89 | if format_id == 'm3u8': | |
eb47569f S |
90 | continue |
91 | height = self._search_regex( | |
92 | r'^(\d+)[pP]$', format_id, 'height', default=None) | |
884ae747 S |
93 | formats.append({ |
94 | 'url': video_url, | |
eb47569f | 95 | 'format_id': '%s-%s' % (vcodec, format_id), |
884ae747 | 96 | 'vcodec': vcodec, |
eb47569f | 97 | 'height': int_or_none(height), |
7584e38c | 98 | 'filesize': int_or_none(item.get('video_files_size', {}).get(vcodec, {}).get(format_id)), |
884ae747 | 99 | }) |
fb8b8fdd S |
100 | self._sort_formats(formats) |
101 | ||
102 | return { | |
103 | 'id': video_id, | |
884ae747 | 104 | 'display_id': display_id, |
fb8b8fdd S |
105 | 'title': title, |
106 | 'description': description, | |
107 | 'thumbnail': thumbnail, | |
884ae747 S |
108 | 'duration': duration, |
109 | 'age_limit': age_limit, | |
fb8b8fdd | 110 | 'formats': formats, |
5f6a1245 | 111 | } |