From: Marcel van der Veldt Date: Thu, 17 Oct 2024 13:58:29 +0000 (+0200) Subject: Always detect charset for m3u playlists X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=04c063a474fc7ffef6047afab33f05d33da1a86a;p=music-assistant-server.git Always detect charset for m3u playlists --- diff --git a/music_assistant/server/helpers/audio.py b/music_assistant/server/helpers/audio.py index 30a05ecb..cce84faf 100644 --- a/music_assistant/server/helpers/audio.py +++ b/music_assistant/server/helpers/audio.py @@ -604,7 +604,8 @@ async def get_hls_radio_stream( ) as resp: resp.raise_for_status() raw_data = await resp.read() - encoding = resp.charset or await detect_charset(raw_data) + # NOTE: using resp.charset is not reliable, we need to detect it ourselves + encoding = 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) @@ -681,7 +682,8 @@ async def get_hls_substream( ) as resp: resp.raise_for_status() raw_data = await resp.read() - encoding = resp.charset or await detect_charset(raw_data) + # NOTE: using resp.charset is not reliable, we need to detect it ourselves + encoding = 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): diff --git a/music_assistant/server/helpers/playlists.py b/music_assistant/server/helpers/playlists.py index 8986de7f..a4b14acd 100644 --- a/music_assistant/server/helpers/playlists.py +++ b/music_assistant/server/helpers/playlists.py @@ -11,6 +11,7 @@ from urllib.parse import urlparse from aiohttp import client_exceptions from music_assistant.common.models.errors import InvalidDataError +from music_assistant.server.helpers.util import detect_charset if TYPE_CHECKING: from music_assistant.server import MusicAssistant @@ -146,10 +147,12 @@ async def fetch_playlist(mass: MusicAssistant, url: str) -> list[PlaylistItem]: """Parse an online m3u or pls playlist.""" try: async with mass.http_session.get(url, allow_redirects=True, timeout=5) as resp: - charset = resp.charset or "utf-8" try: - playlist_data = (await resp.content.read(64 * 1024)).decode(charset) - except ValueError as err: + raw_data = await resp.content.read(64 * 1024) + # NOTE: using resp.charset is not reliable, we need to detect it ourselves + encoding = await detect_charset(raw_data) + playlist_data = raw_data.decode(encoding, errors="replace") + except (ValueError, UnicodeDecodeError) as err: msg = f"Could not decode playlist {url}" raise InvalidDataError(msg) from err except TimeoutError as err: