6 Commits
Author SHA1 Message Date
RadexitoandGitHub 87ec210dfe Merge branch 'FunWarry:master' into master 2026-01-24 14:02:42 +00:00
Warry 0ed90ba8c2 refactor: Refactor mpegdash patch logic and update import ordering 2026-01-23 11:52:09 +01:00
Mathéo GevraiseandGitHub 651daa9ca9 Merge pull request #17 from musicalmusicalmusical/master
fix: Handle non-integer AdaptationSet id/group in TIDAL manifests
2026-01-23 11:33:03 +01:00
musicalmusicalmusicalandGitHub 173b40bef2 Add patch 2026-01-16 18:46:45 +00:00
musicalmusicalmusicalandGitHub e5d104e9f3 Update __init__.py 2026-01-16 18:46:31 +00:00
Mathéo GevraiseandGitHub 81f3995aff Merge pull request #12 from Radexito/fix/path_media_crash
[Fix] crash due to missing path_media.
2026-01-15 21:19:59 +01:00
2 changed files with 97 additions and 0 deletions
+6
View File
@@ -7,8 +7,14 @@ import requests
import toml
from tidal_dl_ng.constants import REQUESTS_TIMEOUT_SEC
# Apply mpegdash patch before any tidalapi imports to fix TIDAL manifest parsing
# See: https://github.com/FunWarry/tidal-dl-ng-For-DJ/issues/15
from tidal_dl_ng.helper.mpegdash_patch import apply_mpegdash_patch
from tidal_dl_ng.model.meta import ProjectInformation, ReleaseLatest
apply_mpegdash_patch()
def metadata_project() -> ProjectInformation:
result: ProjectInformation
+91
View File
@@ -0,0 +1,91 @@
"""
Monkey-patch for mpegdash to handle non-integer AdaptationSet id/group attributes.
TIDAL recently started returning MPD manifests with string values like "main"
for the AdaptationSet `id` and `group` attributes, which mpegdash expects to be integers.
This causes a ValueError: invalid literal for int() with base 10: 'main'
This patch modifies the parse_attr_value function to gracefully handle
non-integer values for attributes that are expected to be integers.
"""
import logging
import re
logger = logging.getLogger(__name__)
_patched = False
def _safe_int(value: str) -> int | None:
"""Safely convert a value to int, returning None if conversion fails."""
try:
return int(value)
except (ValueError, TypeError):
return None
def _convert_list(attr_val: str, value_type) -> list[str]:
attr_type = value_type[0] if value_type else str
try:
return [attr_type(elem) for elem in re.split(r"[, ]", attr_val)]
except (ValueError, TypeError):
return [str(elem) for elem in re.split(r"[, ]", attr_val)]
def _convert_single(attr_name: str, attr_val: str, value_type):
if value_type == int:
result = _safe_int(attr_val)
if result is None:
logger.debug(
"mpegdash: Could not convert '%s'='%s' to int, using None",
attr_name,
attr_val,
)
return result
try:
return value_type(attr_val)
except (ValueError, TypeError):
logger.debug(
"mpegdash: Could not convert '%s'='%s' to %s, using None",
attr_name,
attr_val,
value_type.__name__,
)
return None
def apply_mpegdash_patch() -> None:
"""
Apply a monkey-patch to mpegdash to handle string values in integer fields.
This patches the parse_attr_value function in mpegdash.utils to gracefully
handle non-integer values (like "main") for attributes expected to be integers.
"""
global _patched
if _patched:
return
try:
from mpegdash import utils as mpegdash_utils
def patched_parse_attr_value(xmlnode, attr_name, value_type):
if attr_name not in xmlnode.attributes:
return None
attr_val = xmlnode.attributes[attr_name].nodeValue
if isinstance(value_type, list):
return _convert_list(attr_val, value_type)
return _convert_single(attr_name, attr_val, value_type)
mpegdash_utils.parse_attr_value = patched_parse_attr_value
_patched = True
logger.debug("mpegdash patch applied successfully")
except ImportError:
logger.warning("Could not import mpegdash, patch not applied")
except Exception as e:
logger.warning("Failed to apply mpegdash patch: %s", e)