]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/yandexdisk.py
2 from __future__
import unicode_literals
6 from .common
import InfoExtractor
17 class YandexDiskIE(InfoExtractor
):
18 _VALID_URL
= r
'''(?x)https?://
25 co(?:m(?:\.(?:am|ge|tr))?|\.il)|
35 )/(?:[di]/|public.*?\bhash=)(?P<id>[^/?#&]+)'''
38 'url': 'https://yadi.sk/i/VdOeDou8eZs6Y',
39 'md5': 'a4a8d52958c8fddcf9845935070402ae',
41 'id': 'VdOeDou8eZs6Y',
45 'uploader': 'y.botova',
46 'uploader_id': '300043621',
49 'expected_warnings': ['Unable to download JSON metadata'],
51 'url': 'https://yadi.sk/d/h3WAXvDS3Li3Ce',
52 'only_matching': True,
54 'url': 'https://yadi.sk/public?hash=5DZ296JK9GWCLp02f6jrObjnctjRxMs8L6%2B%2FuhNqk38%3D',
55 'only_matching': True,
58 def _real_extract(self
, url
):
59 domain
, video_id
= self
._match
_valid
_url
(url
).groups()
61 webpage
= self
._download
_webpage
(url
, video_id
)
62 store
= self
._parse
_json
(self
._search
_regex
(
63 r
'<script[^>]+id="store-prefetch"[^>]*>\s*({.+?})\s*</script>',
64 webpage
, 'store'), video_id
)
65 resource
= store
['resources'][store
['rootResourceId']]
67 title
= resource
['name']
68 meta
= resource
.get('meta') or {}
70 public_url
= meta
.get('short_url')
72 video_id
= self
._match
_id
(public_url
)
74 source_url
= (self
._download
_json
(
75 'https://cloud-api.yandex.net/v1/disk/public/resources/download',
76 video_id
, query
={'public_key': url}
, fatal
=False) or {}).get('href')
77 video_streams
= resource
.get('videoStreams') or {}
78 video_hash
= resource
.get('hash') or url
79 environment
= store
.get('environment') or {}
80 sk
= environment
.get('sk')
81 yandexuid
= environment
.get('yandexuid')
82 if sk
and yandexuid
and not (source_url
and video_streams
):
83 self
._set
_cookie
(domain
, 'yandexuid', yandexuid
)
86 return (self
._download
_json
(
87 urljoin(url
, '/public/api/') + action
, video_id
, data
=json
.dumps({
90 }).encode(), headers
={
91 'Content-Type': 'text/plain',
92 }, fatal
=False) or {}).get('data') or {}
94 # TODO: figure out how to detect if download limit has
95 # been reached and then avoid unnecessary source format
97 source_url
= call_api('download-url').get('url')
99 video_streams
= call_api('get-video-streams')
105 'format_id': 'source',
106 'ext': determine_ext(title
, meta
.get('ext') or mimetype2ext(meta
.get('mime_type')) or 'mp4'),
108 'filesize': int_or_none(meta
.get('size'))
111 for video
in (video_streams
.get('videos') or []):
112 format_url
= video
.get('url')
115 if video
.get('dimension') == 'adaptive':
116 formats
.extend(self
._extract
_m
3u8_formats
(
117 format_url
, video_id
, 'mp4', 'm3u8_native',
118 m3u8_id
='hls', fatal
=False))
120 size
= video
.get('size') or {}
121 height
= int_or_none(size
.get('height'))
124 format_id
+= '-%dp' % height
127 'format_id': format_id
,
129 'protocol': 'm3u8_native',
131 'width': int_or_none(size
.get('width')),
133 self
._sort
_formats
(formats
)
135 uid
= resource
.get('uid')
136 display_name
= try_get(store
, lambda x
: x
['users'][uid
]['displayName'])
141 'duration': float_or_none(video_streams
.get('duration'), 1000),
142 'uploader': display_name
,
144 'view_count': int_or_none(meta
.get('views_counter')),