From: Marcel van der Veldt Date: Thu, 17 Oct 2024 10:43:10 +0000 (+0200) Subject: fix encoding detection X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=0292091b238e338b69cc43f7365506fd252f925e;p=music-assistant-server.git fix encoding detection --- diff --git a/music_assistant/server/helpers/audio.py b/music_assistant/server/helpers/audio.py index eda1fbb4..30a05ecb 100644 --- a/music_assistant/server/helpers/audio.py +++ b/music_assistant/server/helpers/audio.py @@ -46,7 +46,7 @@ from .playlists import HLS_CONTENT_TYPES, IsHLSPlaylist, PlaylistItem, fetch_pla from .process import AsyncProcess, check_output, communicate from .tags import parse_tags from .throttle_retry import BYPASS_THROTTLER -from .util import TimedAsyncGenerator, create_tempfile +from .util import TimedAsyncGenerator, create_tempfile, detect_charset if TYPE_CHECKING: from music_assistant.common.models.player_queue import QueueItem @@ -603,8 +603,9 @@ async def get_hls_radio_stream( substream_url, headers=HTTP_HEADERS, timeout=timeout ) as resp: resp.raise_for_status() - charset = resp.charset or "utf-8" - substream_m3u_data = await resp.text(charset) + raw_data = await resp.read() + encoding = resp.charset or await detect_charset(raw_data) + substream_m3u_data = raw_data.decode(encoding) # get chunk-parts from the substream hls_chunks = parse_m3u(substream_m3u_data) chunk_seconds = 0 @@ -679,8 +680,9 @@ async def get_hls_substream( url, allow_redirects=True, headers=HTTP_HEADERS, timeout=timeout ) as resp: resp.raise_for_status() - charset = resp.charset or "utf-8" - master_m3u_data = await resp.text(charset) + raw_data = await resp.read() + encoding = resp.charset or await detect_charset(raw_data) + master_m3u_data = raw_data.decode(encoding) substreams = parse_m3u(master_m3u_data) if any(x for x in substreams if x.length and not x.key): # this is already a substream! diff --git a/music_assistant/server/helpers/util.py b/music_assistant/server/helpers/util.py index 95896f6d..6cdde467 100644 --- a/music_assistant/server/helpers/util.py +++ b/music_assistant/server/helpers/util.py @@ -19,6 +19,7 @@ from importlib.metadata import version as pkg_version from types import TracebackType from typing import TYPE_CHECKING, Any, ParamSpec, Self, TypeVar +import cchardet as chardet import ifaddr import memory_tempfile from zeroconf import IPVersion @@ -181,6 +182,14 @@ async def close_async_generator(agen: AsyncGenerator[Any, None]) -> None: await agen.aclose() +async def detect_charset(data: bytes, fallback="utf-8") -> str: + """Detect charset of raw data.""" + try: + return (await asyncio.to_thread(chardet.detect, data))["encoding"] + except (ImportError, AttributeError): + return fallback + + class TaskManager: """ Helper class to run many tasks at once.