diff --git a/youtube_dl/extractor/soundcloud.py b/youtube_dl/extractor/soundcloud.py index 2bc519728..2d60bfebf 100644 --- a/youtube_dl/extractor/soundcloud.py +++ b/youtube_dl/extractor/soundcloud.py @@ -318,6 +318,8 @@ class SoundcloudIE(InfoExtractor): _API_AUTH_QUERY_TEMPLATE = '?client_id=%s' _API_AUTH_URL_PW = 'https://api-auth.soundcloud.com/web-auth/sign-in/password%s' _access_token = None + _HEADERS = {} + _NETRC_MACHINE = 'soundcloud' def _login(self): username, password = self._get_login_info() @@ -338,10 +340,14 @@ class SoundcloudIE(InfoExtractor): } query = self._API_AUTH_QUERY_TEMPLATE % self._CLIENT_ID - login = sanitized_Request(self._API_AUTH_URL_PW % query, json.dumps(payload)) - response = self._download_json(login) - print(response) - return 0 + login = sanitized_Request(self._API_AUTH_URL_PW % query, json.dumps(payload).encode('utf-8')) + response = self._download_json(login, None) + self._access_token = response.get('session').get('access_token') + if not self._access_token: + self.report_warning('Unable to get access token, login may has failed') + else: + self._HEADERS = {'Authorization': 'OAuth ' + self._access_token} + # signature generation @@ -457,7 +463,7 @@ class SoundcloudIE(InfoExtractor): if not format_url: continue stream = self._download_json( - format_url, track_id, query=query, fatal=False) + format_url, track_id, query=query, fatal=False, headers=self._HEADERS) if not isinstance(stream, dict): continue stream_url = url_or_none(stream.get('url')) @@ -555,7 +561,7 @@ class SoundcloudIE(InfoExtractor): info_json_url = self._resolv_url(self._BASE_URL + resolve_title) info = self._download_json( - info_json_url, full_title, 'Downloading info JSON', query=query) + info_json_url, full_title, 'Downloading info JSON', query=query, headers=self._HEADERS) return self._extract_info_dict(info, full_title, token) @@ -571,7 +577,7 @@ class SoundcloudPlaylistBaseIE(SoundcloudIE): 'ids': ','.join([compat_str(t['id']) for t in tracks]), 'playlistId': playlist_id, 'playlistSecretToken': token, - }) + }, headers=self._HEADERS) entries = [] for track in tracks: track_id = str_or_none(track.get('id')) @@ -615,7 +621,7 @@ class SoundcloudSetIE(SoundcloudPlaylistBaseIE): full_title += '/' + token info = self._download_json(self._resolv_url( - self._BASE_URL + full_title), full_title) + self._BASE_URL + full_title), full_title, headers=self._HEADERS) if 'errors' in info: msgs = (compat_str(err['error_message']) for err in info['errors']) @@ -640,7 +646,7 @@ class SoundcloudPagedPlaylistBaseIE(SoundcloudIE): for i in itertools.count(): response = self._download_json( next_href, playlist_id, - 'Downloading track page %s' % (i + 1), query=query) + 'Downloading track page %s' % (i + 1), query=query, headers=self._HEADERS) collection = response['collection'] @@ -762,7 +768,7 @@ class SoundcloudUserIE(SoundcloudPagedPlaylistBaseIE): user = self._download_json( self._resolv_url(self._BASE_URL + uploader), - uploader, 'Downloading user info') + uploader, 'Downloading user info', headers=self._HEADERS) resource = mobj.group('rsrc') or 'all' @@ -787,7 +793,7 @@ class SoundcloudTrackStationIE(SoundcloudPagedPlaylistBaseIE): def _real_extract(self, url): track_name = self._match_id(url) - track = self._download_json(self._resolv_url(url), track_name) + track = self._download_json(self._resolv_url(url), track_name, headers=self._HEADERS) track_id = self._search_regex( r'soundcloud:track-stations:(\d+)', track['id'], 'track id') @@ -820,7 +826,7 @@ class SoundcloudPlaylistIE(SoundcloudPlaylistBaseIE): data = self._download_json( self._API_V2_BASE + 'playlists/' + playlist_id, - playlist_id, 'Downloading playlist', query=query) + playlist_id, 'Downloading playlist', query=query, headers=self._HEADERS) return self._extract_set(data, token) @@ -857,7 +863,7 @@ class SoundcloudSearchIE(SearchInfoExtractor, SoundcloudIE): for i in itertools.count(1): response = self._download_json( next_url, collection_id, 'Downloading page {0}'.format(i), - 'Unable to download API page') + 'Unable to download API page', headers=self._HEADERS) collection = response.get('collection', []) if not collection: diff --git a/youtube_dl/extractor/test.py b/youtube_dl/extractor/test.py deleted file mode 100644 index 36e4fad62..000000000 --- a/youtube_dl/extractor/test.py +++ /dev/null @@ -1,153 +0,0 @@ -import time -import random -import requests -import sys -import getpass - -def sign():#, username=_USERNAME, client_id=_CLIENT_ID, key=_KEY): - zero = 0 - i = a = 1 - mA = 33 - u = 0 #u is actually screenWidth * screenHeight for 1920*1080 = 2073600 - mU = 2073600 - l = 1024 #1046? - mL = 1028 - timestamp = millis = int(round(time.time() * 1000)) - mTimestamp = timestamp - (timestamp - random.randint(50000, 850000)) #hacky timestamp difference - uTimestamp = random.randint(50000, 85000) - w = 42 #1049? - mW = 1049 - b = k = 2 #25? - mB = mK = 25 - underscore = 0 #4, 5? - mUnderscore = 5 - - - #d = '-'.join([str(mInt) for mInt in [a, i, s, w, u, l, b, k]]) - d = '-'.join([str(mInt) for mInt in [mA, i, uTimestamp, mW, mU, mL, mB, mK]]) - print(d) - - c = mUnderscore - - n = _KEY = '0763ed7314c69015fd4a0dc16bbf4b90' - y = '8' #some kind of version?? - r = _USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36" - e = _USERNAME = "tom_heidel@web.de" - t = _CLIENT_ID = 'EXLwg5lHTO2dslU5EePe3xkw0m1h86Cd' #'T5R4kgWS2PRf6lzLyIravUMnKlbIxQag' #'EXLwg5lHTO2dslU5EePe3xkw0m1h86Cd' - - - p = n + y + d + r + e + t + d + n - - h = p - - print(h) - - m = 8011470 - f = 0 - - for f in range(f, len(h)): - m = (m >> 1) + ((1 & m) << 23) - m += ord(h[f]) - m &= 16777215 - - out = str(y) + ':' + str(d) + ':' + format(m, 'x') + ':' + str(c) - - return out - -#print(sign()) - -def signp(a, i, s, w, u, l, b, k, c, n, r, e, t): - ''' - zero = 0 - i = a = 1 - mA = 33 - u = 0 #u is actually screenWidth * screenHeight for 1920*1080 = 2073600 - mU = 2073600 - l = 1024 #1046? - mL = 1028 - timestamp = millis = int(round(time.time() * 1000)) - mTimestamp = timestamp - (timestamp - random.randint(50000, 850000)) #hacky timestamp difference - uTimestamp = random.randint(50000, 85000) - w = 42 #1049? - mW = 1049 - b = k = 2 #25? - mB = mK = 25 - underscore = 0 #4, 5? - mUnderscore = 5 - ''' - - d = '-'.join([str(mInt) for mInt in [a, i, s, w, u, l, b, k]]) - #d = '-'.join([str(mInt) for mInt in [mA, i, uTimestamp, mW, mU, mL, mB, mK]]) - #print(d) - - #c = mUnderscore - - #n = _KEY = '0763ed7314c69015fd4a0dc16bbf4b90' - y = '8' #some kind of version?? - rr = _USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36" - ee = _USERNAME = "tom_heidel@web.de" - tt = _CLIENT_ID = 'EXLwg5lHTO2dslU5EePe3xkw0m1h86Cd' #'T5R4kgWS2PRf6lzLyIravUMnKlbIxQag' #'EXLwg5lHTO2dslU5EePe3xkw0m1h86Cd' - - - p = n + y + d + r + e + t + d + n - - h = p - - #print(h) - - m = 8011470 - f = 0 - - for f in range(f, len(h)): - m = (m >> 1) + ((1 & m) << 23) - m += ord(h[f]) - m &= 16777215 - - #print(m) - - out = str(y) + ':' + str(d) + ':' + format(m, 'x') + ':' + str(c) - - return out - -#sig = signp(33, 1, 193702, 748, 2073600, 1046, 2, 2, 4, "0763ed7314c69015fd4a0dc16bbf4b90", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36", "tom_heidel@web.de", "T5R4kgWS2PRf6lzLyIravUMnKlbIxQag") -#print(sig) -#print(signp(33, 1, -1, 748, 2073600, 1046, 2, 2, 4, "0763ed7314c69015fd4a0dc16bbf4b90", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36", "tom_heidel@web.de", "T5R4kgWS2PRf6lzLyIravUMnKlbIxQag")) -#print(signp(33, 1, 440123, 117, 1800000, 1042, 37, 37, 5, "0763ed7314c69015fd4a0dc16bbf4b90", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36", "tom_heidel@web.de", "T5R4kgWS2PRf6lzLyIravUMnKlbIxQag")) - -#d = "33-1-193702-748-2073600-1046-2-2" -#p = "0763ed7314c69015fd4a0dc16bbf4b90833-1-193702-748-2073600-1046-2-2Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36tom_heidel@web.deT5R4kgWS2PRf6lzLyIravUMnKlbIxQag33-1-193702-748-2073600-1046-2-20763ed7314c69015fd4a0dc16bbf4b90" - -#sig = "8:33-1-193702-748-2073600-1046-2-2:3bfb60:4" - -login_form_hardcoded = { - 'client_id': "T5R4kgWS2PRf6lzLyIravUMnKlbIxQag", - 'recaptcha_pubkey': 'null', - 'recaptcha_response': 'null', - 'credentials': { - 'identifier': "tom_heidel@web.de", - 'password': ''#getpass.getpass() - }, - 'signature': '',#sig, - 'device_id': '00000-000000-000000-000000', - 'user_agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36" - } - -user = input("User: ") -password = getpass.getpass() -sig_soft = signp(33, 1, 193702, 748, 2073600, 1046, 2, 2, 4, "0763ed7314c69015fd4a0dc16bbf4b90", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36", user, "T5R4kgWS2PRf6lzLyIravUMnKlbIxQag") - -login_form_soft = { - 'client_id': "T5R4kgWS2PRf6lzLyIravUMnKlbIxQag", - 'recaptcha_pubkey': 'null', - 'recaptcha_response': 'null', - 'credentials': { - 'identifier': user, - 'password': password - }, - 'signature': sig_soft, - 'device_id': '00000-000000-000000-000000', - 'user_agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36" - } - -r = requests.post("https://api-auth.soundcloud.com/web-auth/sign-in/password?client_id=T5R4kgWS2PRf6lzLyIravUMnKlbIxQag", json=login_form_soft) -print(r.text) \ No newline at end of file