]>
Commit | Line | Data |
---|---|---|
dcdb292f | 1 | # coding: utf-8 |
c66bdc48 DHS |
2 | from __future__ import unicode_literals |
3 | ||
c66bdc48 | 4 | from .common import InfoExtractor |
3d47ee0a | 5 | from ..utils import ( |
3d47ee0a | 6 | int_or_none, |
3d47ee0a | 7 | ) |
c66bdc48 DHS |
8 | |
9 | ||
1418a043 | 10 | class ZingMp3BaseIE(InfoExtractor): |
11 | _VALID_URL_TMPL = r'https?://(?:mp3\.zing|zingmp3)\.vn/(?:%s)/[^/]+/(?P<id>\w+)\.html' | |
12 | _GEO_COUNTRIES = ['VN'] | |
c66bdc48 | 13 | |
1418a043 | 14 | def _extract_item(self, item, fatal): |
15 | item_id = item['id'] | |
16 | title = item.get('name') or item['title'] | |
51156528 | 17 | |
3d47ee0a | 18 | formats = [] |
1418a043 | 19 | for k, v in (item.get('source') or {}).items(): |
20 | if not v: | |
3d47ee0a | 21 | continue |
1418a043 | 22 | if k in ('mp4', 'hls'): |
23 | for res, video_url in v.items(): | |
24 | if not video_url: | |
25 | continue | |
26 | if k == 'hls': | |
27 | formats.extend(self._extract_m3u8_formats( | |
28 | video_url, item_id, 'mp4', | |
29 | 'm3u8_native', m3u8_id=k, fatal=False)) | |
30 | elif k == 'mp4': | |
31 | formats.append({ | |
32 | 'format_id': 'mp4-' + res, | |
33 | 'url': video_url, | |
34 | 'height': int_or_none(self._search_regex( | |
35 | r'^(\d+)p', res, 'resolution', default=None)), | |
36 | }) | |
3d47ee0a | 37 | else: |
1418a043 | 38 | formats.append({ |
3d47ee0a | 39 | 'ext': 'mp3', |
1418a043 | 40 | 'format_id': k, |
41 | 'tbr': int_or_none(k), | |
42 | 'url': self._proto_relative_url(v), | |
43 | 'vcodec': 'none', | |
3d47ee0a | 44 | }) |
1418a043 | 45 | if not formats: |
46 | if not fatal: | |
47 | return | |
48 | msg = item['msg'] | |
49 | if msg == 'Sorry, this content is not available in your country.': | |
b7da73eb | 50 | self.raise_geo_restricted(countries=self._GEO_COUNTRIES, metadata_available=True) |
51 | self.raise_no_formats(msg, expected=True) | |
1418a043 | 52 | self._sort_formats(formats) |
53 | ||
54 | subtitles = None | |
55 | lyric = item.get('lyric') | |
56 | if lyric: | |
57 | subtitles = { | |
58 | 'origin': [{ | |
59 | 'url': lyric, | |
60 | }], | |
61 | } | |
3d47ee0a | 62 | |
1418a043 | 63 | album = item.get('album') or {} |
c66bdc48 DHS |
64 | |
65 | return { | |
1418a043 | 66 | 'id': item_id, |
67 | 'title': title, | |
3d47ee0a | 68 | 'formats': formats, |
1418a043 | 69 | 'thumbnail': item.get('thumbnail'), |
70 | 'subtitles': subtitles, | |
71 | 'duration': int_or_none(item.get('duration')), | |
72 | 'track': title, | |
73 | 'artist': item.get('artists_names'), | |
74 | 'album': album.get('name') or album.get('title'), | |
75 | 'album_artist': album.get('artists_names'), | |
c66bdc48 DHS |
76 | } |
77 | ||
1418a043 | 78 | def _real_extract(self, url): |
79 | page_id = self._match_id(url) | |
80 | webpage = self._download_webpage( | |
81 | url.replace('://zingmp3.vn/', '://mp3.zing.vn/'), | |
82 | page_id, query={'play_song': 1}) | |
83 | data_path = self._search_regex( | |
84 | r'data-xml="([^"]+)', webpage, 'data path') | |
85 | return self._process_data(self._download_json( | |
86 | 'https://mp3.zing.vn/xhr' + data_path, page_id)['data']) | |
c66bdc48 DHS |
87 | |
88 | ||
1418a043 | 89 | class ZingMp3IE(ZingMp3BaseIE): |
90 | _VALID_URL = ZingMp3BaseIE._VALID_URL_TMPL % 'bai-hat|video-clip' | |
c66bdc48 DHS |
91 | _TESTS = [{ |
92 | 'url': 'http://mp3.zing.vn/bai-hat/Xa-Mai-Xa-Bao-Thy/ZWZB9WAB.html', | |
4ffc3103 | 93 | 'md5': 'ead7ae13693b3205cbc89536a077daed', |
c66bdc48 DHS |
94 | 'info_dict': { |
95 | 'id': 'ZWZB9WAB', | |
4ffc3103 | 96 | 'title': 'Xa Mãi Xa', |
c66bdc48 | 97 | 'ext': 'mp3', |
1418a043 | 98 | 'thumbnail': r're:^https?://.+\.jpg', |
99 | 'subtitles': { | |
100 | 'origin': [{ | |
101 | 'ext': 'lrc', | |
102 | }] | |
103 | }, | |
104 | 'duration': 255, | |
105 | 'track': 'Xa Mãi Xa', | |
106 | 'artist': 'Bảo Thy', | |
107 | 'album': 'Special Album', | |
108 | 'album_artist': 'Bảo Thy', | |
c66bdc48 | 109 | }, |
3d47ee0a | 110 | }, { |
1418a043 | 111 | 'url': 'https://mp3.zing.vn/video-clip/Suong-Hoa-Dua-Loi-K-ICM-RYO/ZO8ZF7C7.html', |
112 | 'md5': 'e9c972b693aa88301ef981c8151c4343', | |
3d47ee0a | 113 | 'info_dict': { |
1418a043 | 114 | 'id': 'ZO8ZF7C7', |
115 | 'title': 'Sương Hoa Đưa Lối', | |
3d47ee0a | 116 | 'ext': 'mp4', |
1418a043 | 117 | 'thumbnail': r're:^https?://.+\.jpg', |
118 | 'duration': 207, | |
119 | 'track': 'Sương Hoa Đưa Lối', | |
120 | 'artist': 'K-ICM, RYO', | |
3d47ee0a RA |
121 | }, |
122 | }, { | |
1418a043 | 123 | 'url': 'https://zingmp3.vn/bai-hat/Xa-Mai-Xa-Bao-Thy/ZWZB9WAB.html', |
124 | 'only_matching': True, | |
125 | }] | |
126 | IE_NAME = 'zingmp3' | |
127 | IE_DESC = 'mp3.zing.vn' | |
128 | ||
129 | def _process_data(self, data): | |
130 | return self._extract_item(data, True) | |
131 | ||
132 | ||
133 | class ZingMp3AlbumIE(ZingMp3BaseIE): | |
134 | _VALID_URL = ZingMp3BaseIE._VALID_URL_TMPL % 'album|playlist' | |
135 | _TESTS = [{ | |
43abd799 S |
136 | 'url': 'http://mp3.zing.vn/album/Lau-Dai-Tinh-Ai-Bang-Kieu-Minh-Tuyet/ZWZBWDAF.html', |
137 | 'info_dict': { | |
138 | '_type': 'playlist', | |
139 | 'id': 'ZWZBWDAF', | |
1418a043 | 140 | 'title': 'Lâu Đài Tình Ái', |
c66bdc48 | 141 | }, |
43abd799 S |
142 | 'playlist_count': 10, |
143 | }, { | |
144 | 'url': 'http://mp3.zing.vn/playlist/Duong-Hong-Loan-apollobee/IWCAACCB.html', | |
145 | 'only_matching': True, | |
1418a043 | 146 | }, { |
147 | 'url': 'https://zingmp3.vn/album/Lau-Dai-Tinh-Ai-Bang-Kieu-Minh-Tuyet/ZWZBWDAF.html', | |
148 | 'only_matching': True, | |
43abd799 | 149 | }] |
1418a043 | 150 | IE_NAME = 'zingmp3:album' |
151 | ||
152 | def _process_data(self, data): | |
153 | def entries(): | |
154 | for item in (data.get('items') or []): | |
155 | entry = self._extract_item(item, False) | |
156 | if entry: | |
157 | yield entry | |
158 | info = data.get('info') or {} | |
159 | return self.playlist_result( | |
160 | entries(), info.get('id'), info.get('name') or info.get('title')) |