]>
Commit | Line | Data |
---|---|---|
cbbe6663 S |
1 | # coding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
4 | from .common import InfoExtractor | |
5 | from ..compat import compat_str | |
6 | from ..utils import ( | |
7 | determine_ext, | |
8 | float_or_none, | |
9 | int_or_none, | |
10 | try_get, | |
11 | urlencode_postdata, | |
12 | ) | |
13 | ||
14 | ||
15 | class YandexDiskIE(InfoExtractor): | |
8519b88f | 16 | _VALID_URL = r'https?://yadi\.sk/[di]/(?P<id>[^/?#&]+)' |
cbbe6663 | 17 | |
8519b88f | 18 | _TESTS = [{ |
cbbe6663 S |
19 | 'url': 'https://yadi.sk/i/VdOeDou8eZs6Y', |
20 | 'md5': '33955d7ae052f15853dc41f35f17581c', | |
21 | 'info_dict': { | |
22 | 'id': 'VdOeDou8eZs6Y', | |
23 | 'ext': 'mp4', | |
24 | 'title': '4.mp4', | |
25 | 'duration': 168.6, | |
26 | 'uploader': 'y.botova', | |
27 | 'uploader_id': '300043621', | |
28 | 'view_count': int, | |
29 | }, | |
8519b88f S |
30 | }, { |
31 | 'url': 'https://yadi.sk/d/h3WAXvDS3Li3Ce', | |
32 | 'only_matching': True, | |
33 | }] | |
cbbe6663 S |
34 | |
35 | def _real_extract(self, url): | |
36 | video_id = self._match_id(url) | |
37 | ||
38 | status = self._download_webpage( | |
39 | 'https://disk.yandex.com/auth/status', video_id, query={ | |
40 | 'urlOrigin': url, | |
41 | 'source': 'public', | |
42 | 'md5': 'false', | |
43 | }) | |
44 | ||
45 | sk = self._search_regex( | |
46 | r'(["\'])sk(?:External)?\1\s*:\s*(["\'])(?P<value>(?:(?!\2).)+)\2', | |
47 | status, 'sk', group='value') | |
48 | ||
49 | webpage = self._download_webpage(url, video_id) | |
50 | ||
51 | models = self._parse_json( | |
52 | self._search_regex( | |
53 | r'<script[^>]+id=["\']models-client[^>]+>\s*(\[.+?\])\s*</script', | |
54 | webpage, 'video JSON'), | |
55 | video_id) | |
56 | ||
57 | data = next( | |
58 | model['data'] for model in models | |
59 | if model.get('model') == 'resource') | |
60 | ||
61 | video_hash = data['id'] | |
62 | title = data['name'] | |
63 | ||
64 | models = self._download_json( | |
65 | 'https://disk.yandex.com/models/', video_id, | |
66 | data=urlencode_postdata({ | |
67 | '_model.0': 'videoInfo', | |
68 | 'id.0': video_hash, | |
69 | '_model.1': 'do-get-resource-url', | |
70 | 'id.1': video_hash, | |
71 | 'version': '13.6', | |
72 | 'sk': sk, | |
73 | }), query={'_m': 'videoInfo'})['models'] | |
74 | ||
75 | videos = try_get(models, lambda x: x[0]['data']['videos'], list) or [] | |
76 | source_url = try_get( | |
77 | models, lambda x: x[1]['data']['file'], compat_str) | |
78 | ||
79 | formats = [] | |
80 | if source_url: | |
81 | formats.append({ | |
82 | 'url': source_url, | |
83 | 'format_id': 'source', | |
84 | 'ext': determine_ext(title, 'mp4'), | |
85 | 'quality': 1, | |
86 | }) | |
87 | for video in videos: | |
88 | format_url = video.get('url') | |
89 | if not format_url: | |
90 | continue | |
91 | if determine_ext(format_url) == 'm3u8': | |
92 | formats.extend(self._extract_m3u8_formats( | |
93 | format_url, video_id, 'mp4', entry_protocol='m3u8_native', | |
94 | m3u8_id='hls', fatal=False)) | |
95 | else: | |
96 | formats.append({ | |
97 | 'url': format_url, | |
98 | }) | |
99 | self._sort_formats(formats) | |
100 | ||
101 | duration = float_or_none(try_get( | |
102 | models, lambda x: x[0]['data']['duration']), 1000) | |
103 | uploader = try_get( | |
104 | data, lambda x: x['user']['display_name'], compat_str) | |
105 | uploader_id = try_get( | |
106 | data, lambda x: x['user']['uid'], compat_str) | |
107 | view_count = int_or_none(try_get( | |
108 | data, lambda x: x['meta']['views_counter'])) | |
109 | ||
110 | return { | |
111 | 'id': video_id, | |
112 | 'title': title, | |
113 | 'duration': duration, | |
114 | 'uploader': uploader, | |
115 | 'uploader_id': uploader_id, | |
116 | 'view_count': view_count, | |
117 | 'formats': formats, | |
118 | } |