rewrote getPreferredBitrate function using mobile API workaround
should be more stable than constantly requesting the CDN
This commit is contained in:
parent
ec38923701
commit
a85396600a
|
@ -29,12 +29,37 @@ class Deezer:
|
||||||
self.selectedAccount = 0
|
self.selectedAccount = 0
|
||||||
self.session = requests.Session()
|
self.session = requests.Session()
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
self.session.post("http://www.deezer.com/", headers=self.http_headers)
|
self.session.post("https://www.deezer.com/", headers=self.http_headers)
|
||||||
self.sid = self.session.cookies.get('sid')
|
self.guest_sid = self.session.cookies.get('sid')
|
||||||
|
|
||||||
def get_token(self):
|
def get_token(self):
|
||||||
token_data = self.gw_api_call('deezer.getUserData')
|
token_data = self.gw_api_call('deezer.getUserData')
|
||||||
return token_data["results"]["checkForm"]
|
return token_data["results"]["checkForm"]
|
||||||
|
|
||||||
|
def get_track_filesizes(self, sng_id):
|
||||||
|
try:
|
||||||
|
site = requests.post(
|
||||||
|
"https://api.deezer.com/1.0/gateway.php",
|
||||||
|
params={
|
||||||
|
'api_key': "4VCYIJUCDLOUELGD1V8WBVYBNVDYOXEWSLLZDONGBBDFVXTZJRXPR29JRLQFO6ZE",
|
||||||
|
'sid': self.guest_sid,
|
||||||
|
'input': '3',
|
||||||
|
'output': '3',
|
||||||
|
'method': 'song_getData'
|
||||||
|
},
|
||||||
|
timeout=30,
|
||||||
|
json={'sng_id': sng_id},
|
||||||
|
headers=self.http_headers
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
time.sleep(2)
|
||||||
|
return self.get_track_filesizes(sng_id)
|
||||||
|
response = site.json()["results"]
|
||||||
|
filesizes = {}
|
||||||
|
for key, value in response.items():
|
||||||
|
if key.startswith("FILESIZE_"):
|
||||||
|
filesizes[key] = value
|
||||||
|
return filesizes
|
||||||
|
|
||||||
def gw_api_call(self, method, args=None):
|
def gw_api_call(self, method, args=None):
|
||||||
if args is None:
|
if args is None:
|
||||||
|
@ -129,13 +154,14 @@ class Deezer:
|
||||||
|
|
||||||
def login_via_arl(self, arl, child=0):
|
def login_via_arl(self, arl, child=0):
|
||||||
cookie_obj = requests.cookies.create_cookie(
|
cookie_obj = requests.cookies.create_cookie(
|
||||||
domain='deezer.com',
|
domain='.deezer.com',
|
||||||
name='arl',
|
name='arl',
|
||||||
value=arl,
|
value=arl,
|
||||||
path="/",
|
path="/",
|
||||||
rest={'HttpOnly': True}
|
rest={'HttpOnly': True}
|
||||||
)
|
)
|
||||||
self.session.cookies.set_cookie(cookie_obj)
|
self.session.cookies.set_cookie(cookie_obj)
|
||||||
|
self.session.cookies.clear(".deezer.com", "/", "sid")
|
||||||
user_data = self.gw_api_call("deezer.getUserData")
|
user_data = self.gw_api_call("deezer.getUserData")
|
||||||
if user_data["results"]["USER"]["USER_ID"] == 0:
|
if user_data["results"]["USER"]["USER_ID"] == 0:
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
|
|
|
@ -56,7 +56,7 @@ def stream_track(dz, track, stream, trackAPI, queueItem, interface=None):
|
||||||
for chunk in request.iter_content(2048):
|
for chunk in request.iter_content(2048):
|
||||||
if 'cancel' in queueItem:
|
if 'cancel' in queueItem:
|
||||||
raise downloadCancelled
|
raise downloadCancelled
|
||||||
if (i % 3) == 0 and len(chunk) == 2048:
|
if i % 3 == 0 and len(chunk) == 2048:
|
||||||
chunk = Blowfish.new(blowfish_key, Blowfish.MODE_CBC, b"\x00\x01\x02\x03\x04\x05\x06\x07").decrypt(chunk)
|
chunk = Blowfish.new(blowfish_key, Blowfish.MODE_CBC, b"\x00\x01\x02\x03\x04\x05\x06\x07").decrypt(chunk)
|
||||||
stream.write(chunk)
|
stream.write(chunk)
|
||||||
chunkLength += len(chunk)
|
chunkLength += len(chunk)
|
||||||
|
@ -130,31 +130,42 @@ def formatDate(date, template):
|
||||||
def getPreferredBitrate(dz, track, bitrate, fallback=True):
|
def getPreferredBitrate(dz, track, bitrate, fallback=True):
|
||||||
if 'localTrack' in track:
|
if 'localTrack' in track:
|
||||||
return 0
|
return 0
|
||||||
formatsnon360 = [9, 3, 1] # flac, mp3_320, mp3_128
|
|
||||||
formats360 = [15, 14, 13] # 360_hq, 360_mq, 360_lq
|
formats_non_360 = {
|
||||||
if not fallback:
|
9: "FLAC",
|
||||||
errorNum = -100
|
3: "MP3_320",
|
||||||
formats = formats360
|
1: "MP3_128",
|
||||||
formats.extend(formatsnon360)
|
}
|
||||||
elif int(bitrate) in formats360:
|
formats_360 = {
|
||||||
errorNum = -200
|
15: "MP4_RA3",
|
||||||
formats = formats360
|
14: "MP4_RA2",
|
||||||
else:
|
13: "MP4_RA1",
|
||||||
errorNum = 8
|
}
|
||||||
formats = formatsnon360
|
|
||||||
|
|
||||||
for formatNum in formats:
|
if not fallback:
|
||||||
if formatNum <= int(bitrate):
|
error_num = -100
|
||||||
request = get(dz.get_track_stream_url(track['id'], track['MD5'], track['mediaVersion'], formatNum), stream=True)
|
formats = formats360
|
||||||
try:
|
formats.extend(formats_non_360)
|
||||||
request.raise_for_status()
|
elif int(bitrate) in formats_360:
|
||||||
except HTTPError: # if the format is not available, Deezer returns a 403 error
|
error_num = -200
|
||||||
|
formats = formats_360
|
||||||
|
else:
|
||||||
|
error_num = 8
|
||||||
|
formats = formats_non_360
|
||||||
|
|
||||||
|
filesizes = dz.get_track_filesizes(track["id"])
|
||||||
|
|
||||||
|
for format_num, format in formats.items():
|
||||||
|
if format_num <= int(bitrate):
|
||||||
|
if f"FILESIZE_{format}" in filesizes and int(filesizes[f"FILESIZE_{format}"]) != 0:
|
||||||
|
return format_num
|
||||||
|
else:
|
||||||
if fallback:
|
if fallback:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
return errorNum
|
return error_num
|
||||||
return formatNum
|
|
||||||
return errorNum # fallback is enabled and loop went through all formats
|
return error_num # fallback is enabled and loop went through all formats
|
||||||
|
|
||||||
|
|
||||||
def parseEssentialTrackData(track, trackAPI):
|
def parseEssentialTrackData(track, trackAPI):
|
||||||
|
|
Loading…
Reference in New Issue