Improved MQA detection
- Downloads the first 163824 bytes and check for MQA - Now properly downloads the file as any other track - Already existing track check working
This commit is contained in:
@@ -151,8 +151,7 @@ file in order to get properly detected.
|
||||
[@purpl3F0x](https://github.com/purpl3F0x) and [mqaid](https://github.com/redsudo/mqaid) by
|
||||
[@redsudo](https://github.com/redsudo).**
|
||||
|
||||
**NOTE: `fix_mqa` is experimental! May not detect already existing tracks,
|
||||
slower as normal download and could be not working at all**
|
||||
**NOTE: `fix_mqa` is enabled which is experimental! May be slower as normal download and could not be working at all**
|
||||
|
||||
<!-- Contact -->
|
||||
## Contact
|
||||
|
||||
47
interface.py
47
interface.py
@@ -12,7 +12,7 @@ import ffmpeg
|
||||
from tqdm import tqdm
|
||||
|
||||
from utils.models import *
|
||||
from utils.utils import sanitise_name, silentremove, download_to_temp, create_temp_filename
|
||||
from utils.utils import sanitise_name, silentremove, download_to_temp, create_temp_filename, create_requests_session
|
||||
from .mqa_identifier_python.mqa_identifier import MqaIdentifier
|
||||
from .tidal_api import TidalTvSession, TidalApi, SessionStorage, TidalMobileSession, SessionType
|
||||
|
||||
@@ -357,21 +357,16 @@ class ModuleInterface:
|
||||
else:
|
||||
# check if MQA
|
||||
if track_codec is CodecEnum.MQA and self.settings['fix_mqa']:
|
||||
self.print(f'"fix_mqa" is enabled which is experimental! May not detect already existing tracks, '
|
||||
f'slower as normal download and could be not working at all', drop_level=1)
|
||||
self.print(f'=== Downloading MQA {track_name} ({track_id}) ===', drop_level=1)
|
||||
indent_level = self.oprinter.indent_number - self.oprinter.multiplier
|
||||
# download the file to analyze it
|
||||
temp_file_path = download_to_temp(manifest['urls'][0], enable_progress_bar=True,
|
||||
indent_level=indent_level)
|
||||
download_args = {'temp_file_path': temp_file_path}
|
||||
self.print(f'"fix_mqa" is enabled which is experimental! May be slower as normal download and could '
|
||||
f'not be working at all', drop_level=1)
|
||||
# download the first chunk of the flac file to analyze it
|
||||
temp_file_path = self.download_temp_header(manifest['urls'][0])
|
||||
|
||||
# detect MQA file
|
||||
mqa_file = MqaIdentifier(temp_file_path)
|
||||
|
||||
self.print(f'=== MQA {track_id} downloaded ===', drop_level=1)
|
||||
else:
|
||||
download_args = {'file_url': manifest['urls'][0]}
|
||||
# add the file to download_args
|
||||
download_args = {'file_url': manifest['urls'][0]}
|
||||
|
||||
bit_depth = 24 if track_codec in [CodecEnum.EAC3, CodecEnum.MHA1] else 16
|
||||
sample_rate = 48 if track_codec in [CodecEnum.EAC3, CodecEnum.MHA1, CodecEnum.AC4] else 44.1
|
||||
@@ -405,6 +400,24 @@ class ModuleInterface:
|
||||
|
||||
return track_info
|
||||
|
||||
@staticmethod
|
||||
def download_temp_header(file_url: str, chunk_size: int = 16384) -> str:
|
||||
# create flac temp_location
|
||||
temp_location = create_temp_filename() + '.flac'
|
||||
|
||||
# create session and download the file to the temp_location
|
||||
r_session = create_requests_session()
|
||||
|
||||
r = r_session.get(file_url, stream=True, verify=False)
|
||||
with open(temp_location, 'wb') as f:
|
||||
# only download the first chunk_size bytes
|
||||
for chunk in r.iter_content(chunk_size=chunk_size):
|
||||
if chunk: # filter out keep-alive new chunks
|
||||
f.write(chunk)
|
||||
break
|
||||
|
||||
return temp_location
|
||||
|
||||
@staticmethod
|
||||
def parse_mpd(xml: bytes) -> list:
|
||||
xml = xml.decode('UTF-8')
|
||||
@@ -466,17 +479,13 @@ class ModuleInterface:
|
||||
|
||||
return tracks
|
||||
|
||||
def get_track_download(self, file_url: str = None, temp_file_path: str = None, audio_track: AudioTrack = None) \
|
||||
def get_track_download(self, file_url: str = None, audio_track: AudioTrack = None) \
|
||||
-> TrackDownloadInfo:
|
||||
# only file_url, temp_file_path or audio_track at a time, with file_url > temp_file_path
|
||||
# only file_url or audio_track at a time
|
||||
|
||||
# MHA1 or EC-3
|
||||
# MHA1, EC-3 or MQA
|
||||
if file_url:
|
||||
return TrackDownloadInfo(download_type=DownloadEnum.URL, file_url=file_url)
|
||||
|
||||
# MQA file with enabled "fix_mqa"
|
||||
if temp_file_path:
|
||||
return TrackDownloadInfo(download_type=DownloadEnum.TEMP_FILE_PATH, temp_file_path=temp_file_path)
|
||||
|
||||
# MPEG-DASH
|
||||
# use the total_file size for a better progress bar? Is it even possible to calculate the total size from MPD?
|
||||
|
||||
@@ -58,7 +58,7 @@ MAGIC = 51007556744 # int.from_bytes(bytes.fromhex('0be0498c88'), 'big') jesus
|
||||
|
||||
|
||||
class MqaIdentifier:
|
||||
def __init__(self, flac_file_path: Path):
|
||||
def __init__(self, flac_file_path: str or Path):
|
||||
self.is_mqa = False
|
||||
self.is_mqa_studio = False
|
||||
self.original_sample_rate = None
|
||||
@@ -76,7 +76,7 @@ class MqaIdentifier:
|
||||
return int(sample_rate)
|
||||
return sample_rate
|
||||
|
||||
def _decode_flac_samples(self, flac_file_path) -> list:
|
||||
def _decode_flac_samples(self, flac_file_path: str or Path) -> list:
|
||||
"""
|
||||
Decodes a 16/24bit flac file to a samples list
|
||||
|
||||
@@ -89,7 +89,11 @@ class MqaIdentifier:
|
||||
if magic == b'fLaC':
|
||||
with flac.BitInputStream(f) as bf:
|
||||
f = io.BytesIO()
|
||||
flac.decode_file(bf, f, seconds=1)
|
||||
# ignore EOFError
|
||||
try:
|
||||
flac.decode_file(bf, f, seconds=1)
|
||||
except EOFError:
|
||||
pass
|
||||
f.seek(0)
|
||||
|
||||
with wave.open(f) as wf:
|
||||
@@ -108,7 +112,7 @@ class MqaIdentifier:
|
||||
|
||||
return list(iter_data(wf.readframes(framerate)))
|
||||
|
||||
def detect(self, flac_file_path) -> bool:
|
||||
def detect(self, flac_file_path: str or Path) -> bool:
|
||||
"""
|
||||
Detects if the FLAC file is a MQA file and also detects if it's MQA Studio (blue) and the originalSampleRate
|
||||
|
||||
|
||||
Reference in New Issue
Block a user