Merge pull request #33 from uhwot/hires-flac
added hires flac support, rewrote session selection entirely
This commit is contained in:
55
interface.py
55
interface.py
@@ -23,7 +23,7 @@ module_information = ModuleInformation(
|
|||||||
global_settings={
|
global_settings={
|
||||||
'tv_token': '7m7Ap0JC9j1cOM3n',
|
'tv_token': '7m7Ap0JC9j1cOM3n',
|
||||||
'tv_secret': 'vRAdA108tlvkJpTsGZS8rGZ7xTlbJ0qaZ2K9saEzsgY=',
|
'tv_secret': 'vRAdA108tlvkJpTsGZS8rGZ7xTlbJ0qaZ2K9saEzsgY=',
|
||||||
'mobile_atmos_token': 'dN2N95wCyEBTllu4',
|
'mobile_atmos_token': 'km8T1xS355y7dd3H',
|
||||||
'mobile_default_token': 'WAU9gXp3tHhK4Nns',
|
'mobile_default_token': 'WAU9gXp3tHhK4Nns',
|
||||||
'enable_mobile': True,
|
'enable_mobile': True,
|
||||||
'force_non_spatial': False,
|
'force_non_spatial': False,
|
||||||
@@ -424,26 +424,43 @@ class ModuleInterface:
|
|||||||
# add the region locked album to the cache in order to properly use it later (force_album_format)
|
# add the region locked album to the cache in order to properly use it later (force_album_format)
|
||||||
self.album_cache = {album_id: album_data}
|
self.album_cache = {album_id: album_data}
|
||||||
|
|
||||||
# check if album is only available in LOSSLESS and STEREO, so it switches to the MOBILE_DEFAULT which will
|
media_tags = track_data['mediaMetadata']['tags']
|
||||||
# get FLACs faster, instead of using MPEG-DASH
|
format = None
|
||||||
# lmao what did I smoke when I wrote this, track_data and not album_data!
|
if 'HIRES_LOSSLESS' in media_tags and quality_tier is QualityEnum.HIFI:
|
||||||
if (self.settings['force_non_spatial'] or (
|
format = 'flac_hires'
|
||||||
(quality_tier is QualityEnum.LOSSLESS or track_data.get('audioQuality') == 'LOSSLESS')
|
if 'SONY_360RA' in media_tags and not format and not self.settings['force_non_spatial']:
|
||||||
and track_data.get('audioModes') == ['STEREO'])) and (
|
format = '360ra'
|
||||||
SessionType.MOBILE_DEFAULT.name in self.available_sessions):
|
if 'DOLBY_ATMOS' in media_tags and not format and not self.settings['force_non_spatial']:
|
||||||
self.session.default = SessionType.MOBILE_DEFAULT
|
if self.settings['prefer_ac4']:
|
||||||
elif (track_data.get('audioModes') == ['SONY_360RA']
|
format = 'ac4'
|
||||||
or ('DOLBY_ATMOS' in track_data.get('audioModes') and self.settings['prefer_ac4'])) \
|
else:
|
||||||
and SessionType.MOBILE_ATMOS.name in self.available_sessions:
|
format = 'ac3'
|
||||||
self.session.default = SessionType.MOBILE_ATMOS
|
|
||||||
|
session = {
|
||||||
|
'flac_hires': SessionType.MOBILE_ATMOS,
|
||||||
|
'360ra': SessionType.MOBILE_ATMOS,
|
||||||
|
'ac4': SessionType.MOBILE_ATMOS,
|
||||||
|
'ac3': SessionType.TV,
|
||||||
|
# MOBILE_DEFAULT is used whenever possible to avoid MPEG-DASH, which slows downloading
|
||||||
|
None: SessionType.MOBILE_DEFAULT,
|
||||||
|
}[format]
|
||||||
|
|
||||||
|
if not format and 'SONY_360RA' in media_tags:
|
||||||
|
# if 360RA is available, we don't use the mobile session here because that will get 360RA
|
||||||
|
# there are no tracks with both 360RA and atmos afaik,
|
||||||
|
# so this shouldn't be an issue for now
|
||||||
|
session = SessionType.TV
|
||||||
|
|
||||||
|
if session.name in self.available_sessions:
|
||||||
|
self.session.default = session
|
||||||
else:
|
else:
|
||||||
self.session.default = SessionType.TV
|
format = None
|
||||||
|
|
||||||
# define all default values in case the stream_data is None (region locked)
|
# define all default values in case the stream_data is None (region locked)
|
||||||
audio_track, mqa_file, track_codec, bitrate, download_args, error = None, None, CodecEnum.FLAC, None, None, None
|
audio_track, mqa_file, track_codec, bitrate, download_args, error = None, None, CodecEnum.FLAC, None, None, None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
stream_data = self.session.get_stream_url(track_id, self.quality_parse[quality_tier])
|
stream_data = self.session.get_stream_url(track_id, self.quality_parse[quality_tier] if format != 'flac_hires' else 'HI_RES_LOSSLESS')
|
||||||
except TidalRequestError as e:
|
except TidalRequestError as e:
|
||||||
error = e
|
error = e
|
||||||
# definitely region locked
|
# definitely region locked
|
||||||
@@ -489,7 +506,8 @@ class ModuleInterface:
|
|||||||
download_args = {'file_url': manifest['urls'][0]}
|
download_args = {'file_url': manifest['urls'][0]}
|
||||||
|
|
||||||
# https://en.wikipedia.org/wiki/Audio_bit_depth#cite_ref-1
|
# https://en.wikipedia.org/wiki/Audio_bit_depth#cite_ref-1
|
||||||
bit_depth = 16 if track_codec in {CodecEnum.FLAC, CodecEnum.ALAC} else None
|
bit_depth = (24 if stream_data and stream_data['audioQuality'] == 'HI_RES_LOSSLESS' else 16) \
|
||||||
|
if track_codec in {CodecEnum.FLAC, CodecEnum.ALAC} else None
|
||||||
sample_rate = 48 if track_codec in {CodecEnum.EAC3, CodecEnum.MHA1, CodecEnum.AC4} else 44.1
|
sample_rate = 48 if track_codec in {CodecEnum.EAC3, CodecEnum.MHA1, CodecEnum.AC4} else 44.1
|
||||||
|
|
||||||
if stream_data:
|
if stream_data:
|
||||||
@@ -498,7 +516,8 @@ class ModuleInterface:
|
|||||||
'LOW': 96,
|
'LOW': 96,
|
||||||
'HIGH': 320,
|
'HIGH': 320,
|
||||||
'LOSSLESS': 1411,
|
'LOSSLESS': 1411,
|
||||||
'HI_RES': None
|
'HI_RES': None,
|
||||||
|
'HI_RES_LOSSLESS': None
|
||||||
}[stream_data['audioQuality']]
|
}[stream_data['audioQuality']]
|
||||||
|
|
||||||
# manually set bitrate for immersive formats
|
# manually set bitrate for immersive formats
|
||||||
@@ -514,6 +533,8 @@ class ModuleInterface:
|
|||||||
# more precise bitrate tidal uses MPEG-DASH
|
# more precise bitrate tidal uses MPEG-DASH
|
||||||
if audio_track:
|
if audio_track:
|
||||||
bitrate = audio_track.bitrate // 1000
|
bitrate = audio_track.bitrate // 1000
|
||||||
|
if stream_data['audioQuality'] == 'HI_RES_LOSSLESS':
|
||||||
|
sample_rate = audio_track.sample_rate / 1000
|
||||||
|
|
||||||
# now set everything for MQA
|
# now set everything for MQA
|
||||||
if mqa_file is not None and mqa_file.is_mqa:
|
if mqa_file is not None and mqa_file.is_mqa:
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class TidalApi(object):
|
|||||||
return resp_json
|
return resp_json
|
||||||
|
|
||||||
def get_stream_url(self, track_id, quality):
|
def get_stream_url(self, track_id, quality):
|
||||||
return self._get('tracks/' + str(track_id) + '/playbackinfopostpaywall', {
|
return self._get('tracks/' + str(track_id) + '/playbackinfopostpaywall/v4', {
|
||||||
'playbackmode': 'STREAM',
|
'playbackmode': 'STREAM',
|
||||||
'assetpresentation': 'FULL',
|
'assetpresentation': 'FULL',
|
||||||
'audioquality': quality,
|
'audioquality': quality,
|
||||||
|
|||||||
Reference in New Issue
Block a user