]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/skeb.py
2 from __future__
import unicode_literals
4 from .common
import InfoExtractor
5 from ..utils
import ExtractorError
, determine_ext
, parse_qs
, traverse_obj
8 class SkebIE(InfoExtractor
):
9 _VALID_URL
= r
'https?://skeb\.jp/@[^/]+/works/(?P<id>\d+)'
12 'url': 'https://skeb.jp/@riiru_wm/works/10',
15 'title': '内容はおまかせします! by 姫ノ森りぃる@一周年',
16 'descripion': 'md5:1ec50901efc3437cfbfe3790468d532d',
17 'uploader': '姫ノ森りぃる@一周年',
18 'uploader_id': 'riiru_wm',
21 'url': r
're:https://skeb.+',
22 'thumbnail': r
're:https://skeb.+',
25 'url': r
're:https://skeb.+',
36 'url': 'https://skeb.jp/@furukawa_nob/works/3',
39 'title': 'いつもお世話になってお... by 古川ノブ@音楽とVlo...',
40 'descripion': 'md5:5adc2e41d06d33b558bf7b1faeb7b9c2',
41 'uploader': '古川ノブ@音楽とVlogのVtuber',
42 'uploader_id': 'furukawa_nob',
45 'よろしく', '大丈夫', 'お願い', 'でした',
46 '是非', 'O', 'バー', '遊び', 'おはよう',
49 'url': r
're:https://skeb.+',
50 'thumbnail': r
're:https://skeb.+',
53 'url': r
're:https://skeb.+',
63 'url': 'https://skeb.jp/@mollowmollow/works/6',
66 'title': 'ヒロ。\n\n私のキャラク... by 諸々',
67 'descripion': 'md5:aa6cbf2ba320b50bce219632de195f07',
71 'title': 'ヒロ。\n\n私のキャラク... by 諸々',
72 'descripion': 'md5:aa6cbf2ba320b50bce219632de195f07',
75 'title': 'ヒロ。\n\n私のキャラク... by 諸々',
80 def _real_extract(self
, url
):
81 video_id
= self
._match
_id
(url
)
82 nuxt_data
= self
._search
_nuxt
_data
(self
._download
_webpage
(url
, video_id
), video_id
)
86 'title': nuxt_data
.get('title'),
87 'descripion': nuxt_data
.get('description'),
88 'uploader': traverse_obj(nuxt_data
, ('creator', 'name')),
89 'uploader_id': traverse_obj(nuxt_data
, ('creator', 'screen_name')),
90 'age_limit': 18 if nuxt_data
.get('nsfw') else 0,
91 'tags': nuxt_data
.get('tag_list'),
95 for item
in nuxt_data
.get('previews') or []:
96 vid_url
= item
.get('url')
97 given_ext
= traverse_obj(item
, ('information', 'extension'))
98 preview_ext
= determine_ext(vid_url
, default_ext
=None)
100 content_disposition
= parse_qs(vid_url
)['response-content-disposition'][0]
101 preview_ext
= self
._search
_regex
(
102 r
'filename="[^"]+\.([^\.]+?)"', content_disposition
,
103 'preview file extension', fatal
=False, group
=1)
104 if preview_ext
not in ('mp4', 'mp3'):
106 if not vid_url
or not item
.get('id'):
108 width
, height
= traverse_obj(item
, ('information', 'width')), traverse_obj(item
, ('information', 'height'))
109 if width
is not None and height
is not None:
110 # the longest side is at most 720px for non-client viewers
111 max_size
= max(width
, height
)
112 width
, height
= list(x
* 720 // max_size
for x
in (width
, height
))
115 'id': str(item
['id']),
117 'thumbnail': item
.get('poster_url'),
120 'url': item
.get('vtt_url'),
123 } if item
.get('vtt_url') else None,
126 'duration': traverse_obj(item
, ('information', 'duration')),
127 'fps': traverse_obj(item
, ('information', 'frame_rate')),
128 'ext': preview_ext
or given_ext
,
129 'vcodec': 'none' if preview_ext
== 'mp3' else None,
130 # you'll always get 128kbps MP3 for non-client viewers
131 'abr': 128 if preview_ext
== 'mp3' else None,
135 raise ExtractorError('No video/audio attachment found in this commission.', expected
=True)
136 elif len(entries
) == 1: