]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/zingmp3.py
5 from .common
import InfoExtractor
12 class ZingMp3BaseIE(InfoExtractor
):
13 _VALID_URL_TMPL
= r
'https?://(?:mp3\.zing|zingmp3)\.vn/(?P<type>(?:%s))/[^/]+/(?P<id>\w+)(?:\.html|\?)'
14 _GEO_COUNTRIES
= ['VN']
15 _DOMAIN
= 'https://zingmp3.vn'
17 'bai-hat': '/api/v2/page/get/song',
18 'embed': '/api/v2/page/get/song',
19 'video-clip': '/api/v2/page/get/video',
20 'playlist': '/api/v2/page/get/playlist',
21 'album': '/api/v2/page/get/playlist',
22 'lyric': '/api/v2/lyric/get/lyric',
23 'song_streaming': '/api/v2/song/get/streaming',
26 _API_KEY
= '88265e23d4284f25963e6eedac8fbfa3'
27 _SECRET_KEY
= b
'2aa2d1c561e809b267f3638c4a307aab'
29 def _extract_item(self
, item
, song_id
, type_url
, fatal
):
30 item_id
= item
.get('encodeId') or song_id
31 title
= item
.get('title') or item
.get('alias')
33 if type_url
== 'video-clip':
34 source
= item
.get('streaming')
36 api
= self
.get_api_with_signature(name_api
=self
._SLUG
_API
.get('song_streaming'), param
={'id': item_id}
)
37 source
= self
._download
_json
(api
, video_id
=item_id
).get('data')
40 for k
, v
in (source
or {}).items():
43 if k
in ('mp4', 'hls'):
44 for res
, video_url
in v
.items():
48 formats
.extend(self
._extract
_m
3u8_formats
(
49 video_url
, item_id
, 'mp4',
50 'm3u8_native', m3u8_id
=k
, fatal
=False))
53 'format_id': 'mp4-' + res
,
55 'height': int_or_none(self
._search
_regex
(
56 r
'^(\d+)p', res
, 'resolution', default
=None)),
64 'tbr': int_or_none(k
),
65 'url': self
._proto
_relative
_url
(v
),
72 if msg
== 'Sorry, this content is not available in your country.':
73 self
.raise_geo_restricted(countries
=self
._GEO
_COUNTRIES
, metadata_available
=True)
74 self
.raise_no_formats(msg
, expected
=True)
75 self
._sort
_formats
(formats
)
77 lyric
= item
.get('lyric')
79 api
= self
.get_api_with_signature(name_api
=self
._SLUG
_API
.get("lyric"), param
={'id': item_id}
)
80 info_lyric
= self
._download
_json
(api
, video_id
=item_id
)
81 lyric
= traverse_obj(info_lyric
, ('data', 'file'))
88 album
= item
.get('album') or {}
94 'thumbnail': traverse_obj(item
, 'thumbnail', 'thumbnailM'),
95 'subtitles': subtitles
,
96 'duration': int_or_none(item
.get('duration')),
98 'artist': traverse_obj(item
, 'artistsNames', 'artists_names'),
99 'album': traverse_obj(album
, 'name', 'title'),
100 'album_artist': traverse_obj(album
, 'artistsNames', 'artists_names'),
103 def _real_initialize(self
):
104 if not self
.get_param('cookiefile') and not self
.get_param('cookiesfrombrowser'):
105 self
._request
_webpage
(self
.get_api_with_signature(name_api
=self
._SLUG
_API
['bai-hat'], param
={'id': ''}
),
106 None, note
='Updating cookies')
108 def _real_extract(self
, url
):
109 song_id
, type_url
= self
._match
_valid
_url
(url
).group('id', 'type')
110 api
= self
.get_api_with_signature(name_api
=self
._SLUG
_API
[type_url
], param
={'id': song_id}
)
111 return self
._process
_data
(self
._download
_json
(api
, song_id
)['data'], song_id
, type_url
)
113 def get_api_with_signature(self
, name_api
, param
):
114 param
.update({'ctime': '1'}
)
115 sha256
= hashlib
.sha256(''.join(f
'{i}={param[i]}' for i
in sorted(param
)).encode('utf-8')).hexdigest()
117 'apiKey': self
._API
_KEY
,
118 'sig': hmac
.new(self
._SECRET
_KEY
, f
'{name_api}{sha256}'.encode('utf-8'), hashlib
.sha512
).hexdigest(),
121 return f
'{self._DOMAIN}{name_api}?{urllib.parse.urlencode(data)}'
124 class ZingMp3IE(ZingMp3BaseIE
):
125 _VALID_URL
= ZingMp3BaseIE
._VALID
_URL
_TMPL
% 'bai-hat|video-clip|embed'
127 'url': 'https://mp3.zing.vn/bai-hat/Xa-Mai-Xa-Bao-Thy/ZWZB9WAB.html',
128 'md5': 'ead7ae13693b3205cbc89536a077daed',
131 'title': 'Xa Mãi Xa',
133 'thumbnail': r
're:^https?://.+\.jpg',
140 'track': 'Xa Mãi Xa',
142 'album': 'Special Album',
143 'album_artist': 'Bảo Thy',
146 'url': 'https://zingmp3.vn/video-clip/Suong-Hoa-Dua-Loi-K-ICM-RYO/ZO8ZF7C7.html',
147 'md5': 'c7f23d971ac1a4f675456ed13c9b9612',
150 'title': 'Sương Hoa Đưa Lối',
152 'thumbnail': r
're:^https?://.+\.jpg',
154 'track': 'Sương Hoa Đưa Lối',
155 'artist': 'K-ICM, RYO',
156 'album': 'Sương Hoa Đưa Lối (Single)',
157 'album_artist': 'K-ICM, RYO',
160 'url': 'https://zingmp3.vn/bai-hat/Nguoi-Yeu-Toi-Lanh-Lung-Sat-Da-Mr-Siro/ZZ6IW7OU.html',
161 'md5': '3e9f7a9bd0d965573dbff8d7c68b629d',
164 'title': 'Người Yêu Tôi Lạnh Lùng Sắt Đá',
166 'thumbnail': r
're:^https?://.+\.jpg',
168 'track': 'Người Yêu Tôi Lạnh Lùng Sắt Đá',
169 'artist': 'Mr. Siro',
170 'album': 'Người Yêu Tôi Lạnh Lùng Sắt Đá (Single)',
171 'album_artist': 'Mr. Siro',
174 'url': 'https://zingmp3.vn/embed/song/ZWZEI76B?start=false',
175 'only_matching': True,
177 'url': 'https://zingmp3.vn/bai-hat/Xa-Mai-Xa-Bao-Thy/ZWZB9WAB.html',
178 'only_matching': True,
181 IE_DESC
= 'zingmp3.vn'
183 def _process_data(self
, data
, song_id
, type_url
):
184 return self
._extract
_item
(data
, song_id
, type_url
, True)
187 class ZingMp3AlbumIE(ZingMp3BaseIE
):
188 _VALID_URL
= ZingMp3BaseIE
._VALID
_URL
_TMPL
% 'album|playlist'
190 'url': 'http://mp3.zing.vn/album/Lau-Dai-Tinh-Ai-Bang-Kieu-Minh-Tuyet/ZWZBWDAF.html',
194 'title': 'Lâu Đài Tình Ái',
198 'url': 'https://zingmp3.vn/album/Nhung-Bai-Hat-Hay-Nhat-Cua-Mr-Siro-Mr-Siro/ZWZAEZZD.html',
202 'title': 'Những Bài Hát Hay Nhất Của Mr. Siro',
204 'playlist_count': 49,
206 'url': 'http://mp3.zing.vn/playlist/Duong-Hong-Loan-apollobee/IWCAACCB.html',
207 'only_matching': True,
209 'url': 'https://zingmp3.vn/album/Lau-Dai-Tinh-Ai-Bang-Kieu-Minh-Tuyet/ZWZBWDAF.html',
210 'only_matching': True,
212 IE_NAME
= 'zingmp3:album'
214 def _process_data(self
, data
, song_id
, type_url
):
216 for item
in traverse_obj(data
, ('song', 'items')) or []:
217 entry
= self
._extract
_item
(item
, song_id
, type_url
, False)
221 return self
.playlist_result(entries(), traverse_obj(data
, 'id', 'encodeId'),
222 traverse_obj(data
, 'name', 'title'))