music-assistant: 2.7.11 -> 2.8.4 (#503933)

This commit is contained in:
Emily
2026-04-14 12:55:54 +00:00
committed by GitHub
19 changed files with 214 additions and 171 deletions
@@ -82,7 +82,8 @@ in
allowedTCPPorts =
lib.optional cfg.enable 8097 # Music Assistant stream port
++ lib.optional (lib.elem "airplay" cfg.providers) 7000
++ lib.optional (lib.elem "sendspin" cfg.providers) 8927;
++ lib.optional (lib.elem "sendspin" cfg.providers) 8927
++ lib.optional (lib.elem "snapcast" cfg.providers) 1780;
# The information published by Apple 1 seem to not apply to libraop.
# The closest we could find that represents the port range being used as observed by tcpdump is the ephemeral port range.
# 1: https://support.apple.com/en-us/103229#:~:text=49152%E2%80%93-,65535,-TCP%2C%20UDP
@@ -97,6 +98,7 @@ in
services.avahi = lib.mkIf (lib.elem "airplay_receiver" cfg.providers) {
enable = true;
openFirewall = lib.mkIf cfg.openFirewall true;
publish = {
enable = true;
userServices = true;
@@ -129,7 +131,7 @@ in
++ lib.optionals (lib.elem "airplay_receiver" cfg.providers) [
shairport-sync
]
++ lib.optionals (lib.elem "spotify" cfg.providers) [
++ lib.optionals (lib.elem "spotify" cfg.providers || lib.elem "spotify_connect" cfg.providers) [
librespot-ma
]
++ lib.optionals (lib.elem "snapcast" cfg.providers) [
+3 -12
View File
@@ -4,7 +4,6 @@
bison,
curl,
fetchFromGitHub,
fetchpatch,
ffmpeg-headless,
flex,
gperf,
@@ -26,26 +25,18 @@
stdenv.mkDerivation {
pname = "cliairplay";
# see the beginning of configure.ac for the upstream version number
version = "0.2-unstable-2025-12-30";
version = "1.1-unstable-2026-03-16";
src = fetchFromGitHub {
owner = "music-assistant";
repo = "cliairplay";
# we try to closely match the commit used in the last music-assistant release from
# https://github.com/music-assistant/server/tree/stable/music_assistant/providers/airplay/bin
rev = "4660d886585d6bf8f32e889feec2a0e8975c51dc";
rev = "991c65acc2afa17ffe32e279dbc585b0b7f530f8";
fetchSubmodules = true;
hash = "sha256-oDStn9LdLYWKhZNm7Qfdibs4qsct8gE3RZbTKooQeOM=";
hash = "sha256-m1O4l6gFEGNAyskYcRHcA15cubZnNgkaYjdVThRRX7w=";
};
patches = [
# Support gettext 0.25
(fetchpatch {
url = "https://github.com/music-assistant/cliairplay/commit/92a2445d64c476d740feba1f31c7e5bc768701b7.patch";
hash = "sha256-/YnopvAGHHnQhfr2X1OenLMoF4ZlUq9x8tQZha/XfbQ=";
})
];
nativeBuildInputs = [
autoreconfHook
bison
+3 -3
View File
@@ -16,16 +16,16 @@ let
in
stdenv.mkDerivation {
pname = "libraop";
version = "0-unstable-2026-02-09";
version = "0-unstable-2026-02-20";
src = fetchFromGitHub {
owner = "music-assistant";
repo = "libraop";
# we try to closely match the commit used in the last music-assistant release from
# https://github.com/music-assistant/server/tree/stable/music_assistant/providers/airplay/bin
rev = "f49284282ea4ea740d07fabc230b4182f8c69a74";
rev = "df3c055674c147eeaa9307b7d554b9d46ed6418a";
fetchSubmodules = true;
hash = "sha256-m1ll5vRZx4d/5IWCG24yY/SWEIIz2k/iU84vQKHlCdo=";
hash = "sha256-zD1DggBQjbiD7B/u0hmogXj8NhrzYgVXMyzvHkaM4Hg=";
};
patches = [
@@ -1,8 +1,8 @@
diff --git a/music_assistant/providers/snapcast/constants.py b/music_assistant/providers/snapcast/constants.py
index eb5ecb1a..92f03212 100644
index 8c897c72..d89a0cd2 100644
--- a/music_assistant/providers/snapcast/constants.py
+++ b/music_assistant/providers/snapcast/constants.py
@@ -43,7 +43,8 @@ CONTROL_SOCKET_PATH_TEMPLATE = "/tmp/ma-snapcast-{queue_id}.sock" # noqa: S108
@@ -46,7 +46,8 @@
MASS_STREAM_PREFIX = "Music Assistant - "
MASS_ANNOUNCEMENT_POSTFIX = " (announcement)"
SNAPWEB_DIR = pathlib.Path(__file__).parent.resolve().joinpath("snapweb")
@@ -13,18 +13,18 @@ index eb5ecb1a..92f03212 100644
DEFAULT_SNAPCAST_FORMAT = AudioFormat(
content_type=ContentType.PCM_S16LE,
diff --git a/music_assistant/providers/snapcast/provider.py b/music_assistant/providers/snapcast/provider.py
index 94c197fc..9a344f53 100644
index 049fb934..316b6cf8 100644
--- a/music_assistant/providers/snapcast/provider.py
+++ b/music_assistant/providers/snapcast/provider.py
@@ -32,6 +32,7 @@ from music_assistant.providers.snapcast.constants import (
@@ -35,6 +35,7 @@
CONF_STREAM_IDLE_THRESHOLD,
CONF_USE_EXTERNAL_SERVER,
CONTROL_SCRIPT,
+ CONTROL_SCRIPT_DIR,
CONTROL_SOCKET_PATH_TEMPLATE,
DEFAULT_SNAPSERVER_CONFIG_FILE,
DEFAULT_SNAPSERVER_PLUGIN_DIR,
DEFAULT_SNAPSERVER_PORT,
SNAPWEB_DIR,
@@ -215,6 +216,10 @@ class SnapCastProvider(PlayerProvider):
@@ -270,6 +271,10 @@ async def _builtin_server_runner(self) -> None:
args = [
"snapserver",
@@ -34,23 +34,14 @@ index 94c197fc..9a344f53 100644
+ "--config=/dev/null",
# config settings taken from
# https://raw.githubusercontent.com/badaix/snapcast/86cd4b2b63e750a72e0dfe6a46d47caf01426c8d/server/etc/snapserver.conf
f"--server.datadir={self.mass.storage_path}",
@@ -227,6 +232,7 @@ class SnapCastProvider(PlayerProvider):
f"--stream.buffer={self._snapcast_server_buffer_size}",
f"--stream.chunk_ms={self._snapcast_server_chunk_ms}",
f"--stream.codec={self._snapcast_server_transport_codec}",
+ f"--stream.plugin_dir={CONTROL_SCRIPT_DIR}",
f"--config={self._snapcast_server_config_file}",
@@ -286,8 +291,7 @@ async def _builtin_server_runner(self) -> None:
f"--stream.send_to_muted={str(self._snapcast_server_send_to_muted).lower()}",
f"--streaming_client.initial_volume={self._snapcast_server_initial_volume}",
]
@@ -243,9 +249,7 @@ class SnapCastProvider(PlayerProvider):
# Copy control script after snapserver starts
# (run in executor to avoid blocking)
loop = asyncio.get_running_loop()
- self._controlscript_available = await loop.run_in_executor(
- None, self._setup_controlscript
- )
+ self._controlscript_available = True
def _get_ma_id(self, snap_client_id: str) -> str:
search_dict = self._ids_map.inverse
- loop = asyncio.get_running_loop()
- plugin_dir = await loop.run_in_executor(None, self._setup_controlscript)
+ plugin_dir = CONTROL_SCRIPT_DIR
if plugin_dir is not None:
args.append(f"--stream.plugin_dir={plugin_dir}")
self._controlscript_available = True
@@ -1,16 +1,16 @@
diff --git a/music_assistant/providers/airplay/helpers.py b/music_assistant/providers/airplay/helpers.py
index c5fef7eb..a628622d 100644
index 0d03b2cd..9cd59cf0 100644
--- a/music_assistant/providers/airplay/helpers.py
+++ b/music_assistant/providers/airplay/helpers.py
@@ -6,6 +6,7 @@
import os
import platform
@@ -9,6 +9,7 @@
import socket
import time
from ipaddress import ip_address
+from shutil import which
from typing import TYPE_CHECKING
from zeroconf import IPVersion
@@ -176,7 +177,6 @@ async def check_binary(cli_path: str) -> str | None:
from music_assistant_models.enums import ContentType
@@ -226,7 +227,6 @@ async def check_binary(cli_path: str) -> str | None:
pass
return None
@@ -18,7 +18,7 @@ index c5fef7eb..a628622d 100644
system = platform.system().lower().replace("darwin", "macos")
architecture = platform.machine().lower()
@@ -188,7 +188,7 @@ async def check_binary(cli_path: str) -> str | None:
@@ -238,7 +238,7 @@ async def check_binary(cli_path: str) -> str | None:
raise RuntimeError(f"Unsupported streaming protocol requested: {protocol}")
if bridge_binary := await check_binary(
@@ -1,8 +1,8 @@
diff --git a/music_assistant/helpers/util.py b/music_assistant/helpers/util.py
index bc14912b..0527a831 100644
index e91cd933..ed96d9b5 100644
--- a/music_assistant/helpers/util.py
+++ b/music_assistant/helpers/util.py
@@ -495,30 +495,11 @@ async def load_provider_module(domain: str, requirements: list[str]) -> Provider
@@ -602,30 +602,11 @@ def _get_provider_module(domain: str) -> ProviderModuleType:
"ProviderModuleType", importlib.import_module(f".{domain}", "music_assistant.providers")
)
@@ -35,10 +35,10 @@ index bc14912b..0527a831 100644
async def has_tmpfs_mount() -> bool:
"""Check if we have a tmpfs mount."""
diff --git a/music_assistant/providers/ytmusic/__init__.py b/music_assistant/providers/ytmusic/__init__.py
index 9cc5981a..dc424b0b 100644
index 0ac8a70f..5d74e25b 100644
--- a/music_assistant/providers/ytmusic/__init__.py
+++ b/music_assistant/providers/ytmusic/__init__.py
@@ -200,7 +200,6 @@ class YoutubeMusicProvider(MusicProvider):
@@ -203,7 +203,6 @@ class YoutubeMusicProvider(MusicProvider):
async def handle_async_init(self) -> None:
"""Set up the YTMusic provider."""
logging.getLogger("yt_dlp").setLevel(self.logger.level + 10)
@@ -46,7 +46,7 @@ index 9cc5981a..dc424b0b 100644
self._cookie = self.config.get_value(CONF_COOKIE)
self._po_token_server_url = (
self.config.get_value(CONF_PO_TOKEN_SERVER_URL) or DEFAULT_PO_TOKEN_SERVER_URL
@@ -1091,8 +1090,6 @@ class YoutubeMusicProvider(MusicProvider):
@@ -1103,8 +1102,6 @@ async def _install_packages(self) -> None:
# NOTE: Google breaks things quite often which requires us to update
# some packages very frequently. Installing them dynamically prevents
# us from having to update MA to ensure this provider works.
+16 -16
View File
@@ -1,10 +1,10 @@
diff --git a/music_assistant/controllers/streams/smart_fades/fades.py b/music_assistant/controllers/streams/smart_fades/fades.py
index 03c11ef9..460d53a6 100644
index 59246cce..673c3a10 100644
--- a/music_assistant/controllers/streams/smart_fades/fades.py
+++ b/music_assistant/controllers/streams/smart_fades/fades.py
@@ -76,7 +76,7 @@ class SmartFade(ABC):
async with aiofiles.open(fadeout_filename, "wb") as outfile:
@@ -86,7 +86,7 @@ async def apply(
await outfile.write(fade_out_part)
args = [
- "ffmpeg",
+ "@ffmpeg@",
@@ -12,19 +12,19 @@ index 03c11ef9..460d53a6 100644
"-loglevel",
"error",
diff --git a/music_assistant/helpers/audio.py b/music_assistant/helpers/audio.py
index 0674b009..53158f4d 100644
index f7828a58..698751f9 100644
--- a/music_assistant/helpers/audio.py
+++ b/music_assistant/helpers/audio.py
@@ -103,7 +103,7 @@ async def strip_silence(
reverse: bool = False,
) -> bytes:
"""Strip silence from begin or end of pcm audio using ffmpeg."""
@@ -114,7 +114,7 @@ async def strip_silence(
:param pcm_format: AudioFormat of the audio data.
:param reverse: If True, strip from end instead of beginning.
"""
- args = ["ffmpeg", "-hide_banner", "-loglevel", "quiet"]
+ args = ["@ffmpeg@", "-hide_banner", "-loglevel", "quiet"]
args += [
"-acodec",
pcm_format.content_type.name.lower(),
@@ -1134,7 +1134,7 @@ async def get_silence(
@@ -300,7 +300,7 @@ async def get_silence(
return
# use ffmpeg for all other encodings
args = [
@@ -34,10 +34,10 @@ index 0674b009..53158f4d 100644
"-loglevel",
"quiet",
diff --git a/music_assistant/helpers/ffmpeg.py b/music_assistant/helpers/ffmpeg.py
index 9ea5ea0c..51b1d62b 100644
index 9b7b1bbb..822424dc 100644
--- a/music_assistant/helpers/ffmpeg.py
+++ b/music_assistant/helpers/ffmpeg.py
@@ -249,7 +249,7 @@ def get_ffmpeg_args( # noqa: PLR0915
@@ -267,7 +267,7 @@ def get_ffmpeg_args( # noqa: PLR0915
extra_output_args = []
# generic args
generic_args = [
@@ -46,7 +46,7 @@ index 9ea5ea0c..51b1d62b 100644
"-hide_banner",
"-loglevel",
loglevel,
@@ -416,7 +416,7 @@ async def check_ffmpeg_version() -> None:
@@ -434,7 +434,7 @@ async def check_ffmpeg_version() -> None:
"""Check if ffmpeg is present (with libsoxr support)."""
# check for FFmpeg presence
try:
@@ -56,10 +56,10 @@ index 9ea5ea0c..51b1d62b 100644
raise AudioError(
"FFmpeg binary is missing from system. "
diff --git a/music_assistant/helpers/tags.py b/music_assistant/helpers/tags.py
index fe83301c..d35760b6 100644
index b50633f0..51e8ec7b 100644
--- a/music_assistant/helpers/tags.py
+++ b/music_assistant/helpers/tags.py
@@ -484,7 +484,7 @@ def parse_tags(
@@ -666,7 +666,7 @@ def parse_tags(
Input_file may be a (local) filename or URL accessible by ffmpeg.
"""
args = (
@@ -68,7 +68,7 @@ index fe83301c..d35760b6 100644
"-hide_banner",
"-loglevel",
"fatal",
@@ -551,7 +551,7 @@ def get_file_duration(input_file: str) -> float:
@@ -737,7 +737,7 @@ def get_file_duration(input_file: str) -> float:
NOT Async friendly.
"""
args = (
@@ -77,7 +77,7 @@ index fe83301c..d35760b6 100644
"-hide_banner",
"-loglevel",
"info",
@@ -707,7 +707,7 @@ async def get_embedded_image(input_file: str) -> bytes | None:
@@ -1368,7 +1368,7 @@ async def get_embedded_image(input_file: str) -> bytes | None:
# Use FFmpeg for all other cases (URLs, ID3 tags, Vorbis comments, etc.)
args = [
@@ -1,8 +1,8 @@
diff --git a/music_assistant/helpers/util.py b/music_assistant/helpers/util.py
index 377c7221..aaf6460d 100644
index e91cd933..088e76b7 100644
--- a/music_assistant/helpers/util.py
+++ b/music_assistant/helpers/util.py
@@ -305,7 +305,7 @@ async def get_ip_addresses(include_ipv6: bool = False) -> tuple[str, ...]:
@@ -365,7 +365,7 @@ def call() -> tuple[str, ...]:
continue
# ifaddr returns IPv6 addresses as (address, flowinfo, scope_id) tuples
ip_str = ip.ip[0] if isinstance(ip.ip, tuple) else ip.ip
+4 -3
View File
@@ -2,18 +2,19 @@
lib,
buildPythonPackage,
fetchPypi,
music-assistant,
setuptools,
}:
buildPythonPackage rec {
pname = "music-assistant-frontend";
version = "2.17.73";
version = "2.17.146";
pyproject = true;
src = fetchPypi {
pname = "music_assistant_frontend";
inherit version;
hash = "sha256-vmZa98pT5Cg22fa73/KTrMUqP4Axc1y4x710HCxBzIY=";
hash = "sha256-VU2SXL6SLFiKntmJJtCabBOYOeImYFPHYxvMPmnhmEc=";
};
build-system = [ setuptools ];
@@ -27,6 +28,6 @@ buildPythonPackage rec {
description = "Music Assistant frontend";
homepage = "https://github.com/music-assistant/frontend";
license = lib.licenses.asl20;
maintainers = with lib.maintainers; [ hexa ];
inherit (music-assistant.meta) maintainers;
};
}
@@ -2,7 +2,7 @@ diff --git a/music_assistant/providers/spotify/helpers.py b/music_assistant/prov
index fe7af648..3f5121de 100644
--- a/music_assistant/providers/spotify/helpers.py
+++ b/music_assistant/providers/spotify/helpers.py
@@ -6,6 +6,7 @@ import asyncio
@@ -6,6 +6,7 @@
import os
import platform
import time
@@ -10,7 +10,7 @@ index fe7af648..3f5121de 100644
from typing import TYPE_CHECKING, Any
from urllib.parse import urlencode
@@ -35,12 +36,8 @@ async def get_librespot_binary() -> str:
@@ -35,12 +36,8 @@ async def check_librespot(librespot_path: str) -> str | None:
except OSError:
return None
+68 -70
View File
@@ -14,20 +14,12 @@ let
packageOverrides = self: super: {
music-assistant-frontend = self.callPackage ./frontend.nix { };
music-assistant-models = super.music-assistant-models.overridePythonAttrs (oldAttrs: rec {
version = "1.1.86";
music-assistant-models = super.music-assistant-models.overridePythonAttrs (oldAttrs: {
version = "1.1.115";
src = fetchFromGitHub {
owner = "music-assistant";
repo = "models";
tag = version;
hash = "sha256-dQwFsuelp/3s2CO/5jxNrZcmWxE9xYhrpx0O37Tq/TQ=";
src = oldAttrs.src.override {
hash = "sha256-oEXL0B8JNH4PcltpES375ov7QGs+gtYKlMGr1B7BlKY=";
};
postPatch = ''
substituteInPlace pyproject.toml \
--replace-fail "0.0.0" "${version}"
'';
});
};
};
@@ -40,16 +32,20 @@ let
pythonPath = python.pkgs.makePythonPath providerDependencies;
in
assert
(lib.elem "ariacast" providers) -> throw "music-assistant: ariacast has not been packaged, yet.";
python.pkgs.buildPythonApplication rec {
pname = "music-assistant";
version = "2.7.11";
version = "2.8.4";
pyproject = true;
src = fetchFromGitHub {
owner = "music-assistant";
repo = "server";
tag = version;
hash = "sha256-HLd7PAYdBzpzdfCRPc4elPq3KfzusIXYXTV8fRmo1lU=";
hash = "sha256-/yKnUklNQMsumzj68KIfMN/h7Xsr3Brmwpicam9xuAY=";
};
patches = [
@@ -86,16 +82,14 @@ python.pkgs.buildPythonApplication rec {
postPatch = ''
substituteInPlace pyproject.toml \
--replace-fail "0.0.0" "${version}"
# get-mac is a deprecated alias of getmac since 2018
substituteInPlace pyproject.toml \
--replace-fail "get-mac" "getmac"
--replace-fail "0.0.0" "${version}" \
--replace-fail "==" ">="
rm -rv \
music_assistant/providers/airplay/bin/{cliap2-*,cliraop-*} \
music_assistant/providers/airplay_receiver/bin/{build_binaries.sh,shairport-sync-*} \
music_assistant/providers/spotify/bin
music_assistant/providers/ariacast_receiver/bin/ariacast_* \
music_assistant/providers/spotify/bin/librespot-*
found_bins=$(find music_assistant/ -wholename '*/bin/*' -type f -executable -print0 | tr '\0' ' ')
if [[ -n $found_bins ]]; then
@@ -109,21 +103,12 @@ python.pkgs.buildPythonApplication rec {
];
pythonRelaxDeps = [
"aiofiles"
"aiohttp"
"aiosqlite"
"certifi"
"colorlog"
"cryptography"
"getmac"
"mashumaro"
"numpy"
"orjson"
"pillow"
"podcastparser"
"pycares"
"xmltodict"
"zeroconf"
];
pythonRemoveDeps = [
@@ -131,44 +116,50 @@ python.pkgs.buildPythonApplication rec {
"uv"
];
dependencies = with python.pkgs; [
# Only packages required in pyproject.toml
aiodns
aiofiles
aiohttp
aiohttp-asyncmdnsresolver
aiohttp-fast-zlib
aiortc
aiorun
aiosqlite
awesomeversion
brotli
certifi
chardet
colorlog
cryptography
getmac
gql
ifaddr
librosa
mashumaro
music-assistant-frontend
music-assistant-models
mutagen
orjson
pillow
podcastparser
propcache
python-slugify
shortuuid
unidecode
xmltodict
zeroconf
dependencies =
with python.pkgs;
[
# Only packages required in pyproject.toml
aiodns
aiofiles
aiohttp
aiohttp-asyncmdnsresolver
aiohttp-fast-zlib
aiohttp-socks
aiortc
aiosqlite
awesomeversion
brotli
certifi
chardet
colorlog
cryptography
getmac
gql
ifaddr
librosa
mashumaro
music-assistant-frontend
music-assistant-models
mutagen
numpy
orjson
pillow
podcastparser
propcache
pyjwt
python-slugify
shortuuid
unidecode
xmltodict
zeroconf
# Used in music_assistant/controllers/webserver/helpers/auth_providers.py
# but somehow not part of pyproject.toml
hass-client
];
# Used in music_assistant/controllers/webserver/helpers/auth_providers.py
# but somehow not part of pyproject.toml
hass-client
]
++ gql.optional-dependencies.all
++ pyjwt.optional-dependencies.crypto;
optional-dependencies = with python.pkgs; {
# Required subset of optional-dependencies in pyproject.toml
@@ -185,19 +176,26 @@ python.pkgs.buildPythonApplication rec {
pytestCheckHook
]
++ lib.concatAttrValues optional-dependencies
++ (providerPackages.audible python.pkgs)
++ (providerPackages.dlna python.pkgs)
++ (providerPackages.jellyfin python.pkgs)
++ (providerPackages.opensubsonic python.pkgs)
++ (providerPackages.sendspin python.pkgs)
++ (providerPackages.tidal python.pkgs);
disabledTestPaths = [
# no multicast support in build sandbox:
# "OSError: [Errno 19] No such device"
"tests/providers/jellyfin/test_init.py::test_initial_sync"
"tests/core/test_server_base.py::test_start_and_stop_server"
"tests/core/test_server_base.py::test_events"
"tests/core/test_genres.py"
# provider is missing dependencies
"tests/providers/nicovideo"
"tests/providers/apple_music"
"tests/providers/bandcamp"
"tests/providers/kion_music"
"tests/providers/nicovideo"
"tests/providers/yandex_music"
"tests/providers/zvuk_music"
# mocking music_assistant.providers.airplay.pairing.AirPlayPairing does not work
"tests/providers/airplay/test_player.py::test_start_pairing__pin_decision"
];
pythonImportsCheck = [ "music_assistant" ];
+42 -3
View File
@@ -1,7 +1,7 @@
# Do not edit manually, run ./update-providers.py
{
version = "2.7.11";
version = "2.8.4";
providers = {
airplay =
ps: with ps; [
@@ -19,6 +19,8 @@
ps: with ps; [
gql
];
ariacast_receiver = ps: [
];
audible =
ps: with ps; [
audible
@@ -27,6 +29,8 @@
ps: with ps; [
aioaudiobookshelf
];
bandcamp = ps: [
]; # missing bandcamp-async-api
bbc_sounds =
ps: with ps; [
pytz
@@ -41,6 +45,10 @@
ps: with ps; [
pychromecast
];
coverartarchive = ps: [
];
dashie_kiosk = ps: [
];
deezer =
ps: with ps; [
deezer-python-async
@@ -51,11 +59,16 @@
dlna =
ps: with ps; [
async-upnp-client
defusedxml
];
emby = ps: [
];
fanarttv = ps: [
];
filesystem_local = ps: [
];
filesystem_nfs = ps: [
];
filesystem_smb = ps: [
];
fully_kiosk =
@@ -72,6 +85,10 @@
];
hass_players = ps: [
];
heos =
ps: with ps; [
pyheos
];
ibroadcast = ps: [
]; # missing ibroadcastaio
internet_archive = ps: [
@@ -82,6 +99,8 @@
ps: with ps; [
aiojellyfin
];
kion_music = ps: [
]; # missing yandex-music
lastfm_scrobble =
ps: with ps; [
pylast
@@ -106,6 +125,12 @@
ps: with ps; [
py-opensonic
];
orf_radiothek = ps: [
];
pandora = ps: [
];
party = ps: [
];
phishin = ps: [
];
plex =
@@ -146,6 +171,8 @@
snapcast
websocket-client
];
somafm = ps: [
];
sonos =
ps: with ps; [
aiosonos
@@ -163,14 +190,18 @@
ps: with ps; [
pkce
];
spotify_connect = ps: [
];
spotify_connect =
ps: with ps; [
pkce
];
squeezelite =
ps: with ps; [
aioslimproto
];
subsonic_scrobble = ps: [
];
sync_group = ps: [
];
test = ps: [
];
theaudiodb = ps: [
@@ -183,10 +214,16 @@
];
universal_group = ps: [
];
universal_player = ps: [
];
vban_receiver =
ps: with ps; [
aiovban
];
yandex_music = ps: [
]; # missing yandex-music
yousee = ps: [
];
ytmusic =
ps: with ps; [
bgutil-ytdlp-pot-provider
@@ -194,5 +231,7 @@
yt-dlp
ytmusicapi
]; # missing deno
zvuk_music = ps: [
]; # missing zvuk-music
};
}
@@ -1,5 +1,5 @@
diff --git a/music_assistant/providers/airplay_receiver/helpers.py b/music_assistant/providers/airplay_receiver/helpers.py
index 6f2b35df..dd839b73 100644
index 6f2b35df..d80dd112 100644
--- a/music_assistant/providers/airplay_receiver/helpers.py
+++ b/music_assistant/providers/airplay_receiver/helpers.py
@@ -22,15 +22,9 @@ async def check_shairport_sync(shairport_path: str) -> str | None:
@@ -222,7 +222,7 @@ async def resolve_providers(manifests) -> Set:
version = await get_package_version(attr)
if version not in requirement.specifier:
errors.append(f"{requirement} not satisifed by version {version}")
errors.append(f"{requirement} not satisfied by version {version}")
providers.add(provider)
if errors:
print("\n - ", end="")
@@ -10,14 +10,14 @@
buildPythonPackage rec {
pname = "aioaudiobookshelf";
version = "0.1.13";
version = "0.1.20";
pyproject = true;
src = fetchFromGitHub {
owner = "music-assistant";
repo = "aioaudiobookshelf";
tag = version;
hash = "sha256-63QqoINXY9gKZnyB0at+2C7c6epuda3UQ1/XwzLKnS0=";
hash = "sha256-MEkIcPtNNHvWUBLGRhJGbMnS5cMclGqINuLqvGK8Ivg=";
};
build-system = [
@@ -10,27 +10,37 @@
aiohttp,
av,
mashumaro,
numpy,
orjson,
pillow,
zeroconf,
# test dependencies
pytest-aiohttp,
pytest-cov-stub,
pytest-timeout,
pytest-xdist,
pytestCheckHook,
# meta
music-assistant,
nixosTests,
}:
buildPythonPackage rec {
pname = "aiosendspin";
version = "2.1.0";
version = "4.4.0";
pyproject = true;
src = fetchFromGitHub {
owner = "Sendspin";
repo = "aiosendspin";
tag = version;
hash = "sha256-9VhNtfXH2r/cGkscz51PIK2/66pPOGv0S0IpO0wFvO4=";
hash = "sha256-7edFCGNbECW5rrTbF7vJ4lJUc2IrQZD9VTR3IxJRP08=";
};
# https://github.com/Sendspin/aiosendspin/blob/1.2.0/pyproject.toml#L7
# https://github.com/Sendspin/aiosendspin/blob/4.4.0/pyproject.toml#L7
postPatch = ''
substituteInPlace pyproject.toml \
--replace-fail 'version = "0.0.0"' 'version = "${version}"'
@@ -44,19 +54,29 @@ buildPythonPackage rec {
aiohttp
av
mashumaro
numpy
orjson
pillow
zeroconf
];
doCheck = false; # no tests
nativeCheckInputs = [
pytest-aiohttp
pytest-cov-stub
pytest-timeout
pytest-xdist
pytestCheckHook
];
pythonImportsCheck = [
"aiosendspin"
];
# needs manual compat testing with music-assistant (sendspin provider)
passthru.skipBulkUpdate = true; # nixpkgs-update: no auto update
passthru = {
# needs manual compat testing with music-assistant (sendspin provider)
skipBulkUpdate = true; # nixpkgs-update: no auto update
tests = nixosTests.music-assistant;
};
meta = {
changelog = "https://github.com/Sendspin/aiosendspin/releases/tag/${src.tag}";
@@ -11,14 +11,14 @@
buildPythonPackage rec {
pname = "liblistenbrainz";
version = "0.6.1";
version = "0.7.0";
pyproject = true;
src = fetchFromGitHub {
owner = "metabrainz";
repo = "liblistenbrainz";
tag = "v${version}";
hash = "sha256-2/EUzkC+8u6SQZYstIqJnlWcz74f5UpuXh/r4ImNd0g=";
tag = version;
hash = "sha256-fZgIVGDUJ4Dh/7CIOugvpRP7FoijpsgA3bBKJMmDd7o=";
};
build-system = [
@@ -15,10 +15,11 @@
pytest-cov-stub,
# reverse dependencies
music-assistant,
music-assistant-client,
}:
buildPythonPackage rec {
buildPythonPackage (finalAttrs: {
pname = "music-assistant-models";
# Must be compatible with music-assistant-client package
# nixpkgs-update: no auto update
@@ -28,13 +29,13 @@ buildPythonPackage rec {
src = fetchFromGitHub {
owner = "music-assistant";
repo = "models";
tag = version;
tag = finalAttrs.version;
hash = "sha256-/eNCgAB5G8g1r2fcW27lySEqg+q/1bJvwwyntigGWjo=";
};
postPatch = ''
substituteInPlace pyproject.toml \
--replace-fail "0.0.0" "${version}"
--replace-fail "0.0.0" "${finalAttrs.version}"
'';
build-system = [ setuptools ];
@@ -54,14 +55,14 @@ buildPythonPackage rec {
];
passthru.tests = {
inherit music-assistant-client;
inherit music-assistant music-assistant-client;
};
meta = {
description = "Models used by Music Assistant (shared by client and server";
description = "Models used by Music Assistant (shared by client and server)";
homepage = "https://github.com/music-assistant/models";
changelog = "https://github.com/music-assistant/models/releases/tag/${src.tag}";
changelog = "https://github.com/music-assistant/models/releases/tag/${finalAttrs.src.tag}";
license = lib.licenses.asl20;
maintainers = [ ];
};
}
})
@@ -10,14 +10,14 @@
buildPythonPackage rec {
pname = "py-opensonic";
version = "8.1.2";
version = "8.1.3";
pyproject = true;
src = fetchFromGitHub {
owner = "khers";
repo = "py-opensonic";
tag = "v${version}";
hash = "sha256-lpPRkPLWHzsXhpZ1PVvgNWTQUuuU8N0g7ntqyOAbPlM=";
hash = "sha256-p8vcH0rL2ebFzZCouIEJ1EZCJaxpjQeOUtQug3B88T8=";
};
build-system = [ setuptools ];