]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/yandexdisk.py
2 from __future__
import unicode_literals
7 from .common
import InfoExtractor
18 class YandexDiskIE(InfoExtractor
):
19 _VALID_URL
= r
'''(?x)https?://
26 co(?:m(?:\.(?:am|ge|tr))?|\.il)|
36 )/(?:[di]/|public.*?\bhash=)(?P<id>[^/?#&]+)'''
39 'url': 'https://yadi.sk/i/VdOeDou8eZs6Y',
40 'md5': 'a4a8d52958c8fddcf9845935070402ae',
42 'id': 'VdOeDou8eZs6Y',
46 'uploader': 'y.botova',
47 'uploader_id': '300043621',
50 'expected_warnings': ['Unable to download JSON metadata'],
52 'url': 'https://yadi.sk/d/h3WAXvDS3Li3Ce',
53 'only_matching': True,
55 'url': 'https://yadi.sk/public?hash=5DZ296JK9GWCLp02f6jrObjnctjRxMs8L6%2B%2FuhNqk38%3D',
56 'only_matching': True,
59 def _real_extract(self
, url
):
60 domain
, video_id
= re
.match(self
._VALID
_URL
, url
).groups()
62 webpage
= self
._download
_webpage
(url
, video_id
)
63 store
= self
._parse
_json
(self
._search
_regex
(
64 r
'<script[^>]+id="store-prefetch"[^>]*>\s*({.+?})\s*</script>',
65 webpage
, 'store'), video_id
)
66 resource
= store
['resources'][store
['rootResourceId']]
68 title
= resource
['name']
69 meta
= resource
.get('meta') or {}
71 public_url
= meta
.get('short_url')
73 video_id
= self
._match
_id
(public_url
)
75 source_url
= (self
._download
_json
(
76 'https://cloud-api.yandex.net/v1/disk/public/resources/download',
77 video_id
, query
={'public_key': url}
, fatal
=False) or {}).get('href')
78 video_streams
= resource
.get('videoStreams') or {}
79 video_hash
= resource
.get('hash') or url
80 environment
= store
.get('environment') or {}
81 sk
= environment
.get('sk')
82 yandexuid
= environment
.get('yandexuid')
83 if sk
and yandexuid
and not (source_url
and video_streams
):
84 self
._set
_cookie
(domain
, 'yandexuid', yandexuid
)
87 return (self
._download
_json
(
88 urljoin(url
, '/public/api/') + action
, video_id
, data
=json
.dumps({
91 }).encode(), headers
={
92 'Content-Type': 'text/plain',
93 }, fatal
=False) or {}).get('data') or {}
95 # TODO: figure out how to detect if download limit has
96 # been reached and then avoid unnecessary source format
98 source_url
= call_api('download-url').get('url')
100 video_streams
= call_api('get-video-streams')
106 'format_id': 'source',
107 'ext': determine_ext(title
, meta
.get('ext') or mimetype2ext(meta
.get('mime_type')) or 'mp4'),
109 'filesize': int_or_none(meta
.get('size'))
112 for video
in (video_streams
.get('videos') or []):
113 format_url
= video
.get('url')
116 if video
.get('dimension') == 'adaptive':
117 formats
.extend(self
._extract
_m
3u8_formats
(
118 format_url
, video_id
, 'mp4', 'm3u8_native',
119 m3u8_id
='hls', fatal
=False))
121 size
= video
.get('size') or {}
122 height
= int_or_none(size
.get('height'))
125 format_id
+= '-%dp' % height
128 'format_id': format_id
,
130 'protocol': 'm3u8_native',
132 'width': int_or_none(size
.get('width')),
134 self
._sort
_formats
(formats
)
136 uid
= resource
.get('uid')
137 display_name
= try_get(store
, lambda x
: x
['users'][uid
]['displayName'])
142 'duration': float_or_none(video_streams
.get('duration'), 1000),
143 'uploader': display_name
,
145 'view_count': int_or_none(meta
.get('views_counter')),