Skip to content

Commit b0dff30

Browse files
OzGavclaudemarcelveldt
authored
Fix Universal Group Player producing no audio on some members (#4116)
# What does this implement/fix? <!-- Quick description and explanation of changes. --> When playing to a Universal Group, members that can't use chunked streaming (e.g. Squeezelite, some older Chromecast firmware) got no sound. Universal groups always streamed using chunked encoding to every member, regardless of each member's own configured streaming style so any member that couldn't handle chunked failed silently, and the whole group then stopped after a few seconds. Each member already fetches the audio over its own connection, so the streaming style can safely differ per member. We now pick it from each member's own player settings — the same one it uses for normal (non-group) playback — instead of forcing chunked on everyone. We also guard against the specific crash that left HTTP/1.0 members silent. **Related issue (if applicable):** - related issue music-assistant/support#5214 ## Types of changes <!-- Tick exactly one box. CI (.github/workflows/pr-labels.yaml) derives the label from the ticked box and applies it automatically; the release-notes generator uses that same label to slot this change into the next release notes. --> - [X] Bugfix (non-breaking change which fixes an issue) — `bugfix` - [ ] New feature (non-breaking change which adds functionality) — `new-feature` - [ ] Enhancement to an existing feature — `enhancement` - [ ] New music/player/metadata/plugin provider — `new-provider` - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) — `breaking-change` - [ ] Refactor (no behaviour change) — `refactor` - [ ] Documentation only — `documentation` - [ ] Maintenance / chore — `maintenance` - [ ] CI / workflow change — `ci` - [ ] Dependencies bump — `dependencies` ## Checklist - [X] The code change is tested and works locally. - [X] `pre-commit run --all-files` passes. - [X] `pytest` passes, and tests have been added/updated under `tests/` where applicable. - [ ] For changes to shared models, the companion PR in `music-assistant/models` is linked. - [ ] For changes affecting the UI, the companion PR in `music-assistant/frontend` is linked. - [X] I have read and complied with the project's [AI Policy](https://github.com/music-assistant/.github/blob/main/AI_POLICY.md) for any AI-assisted contributions. - [ ] I have raised a PR against the documentation repository targeting the main or beta branch as appropriate. --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
1 parent 39a1d37 commit b0dff30

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

  • music_assistant/providers/universal_group

music_assistant/providers/universal_group/player.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
from __future__ import annotations
44

55
import asyncio
6+
import contextlib
67
from copy import deepcopy
78
from time import time
89
from typing import TYPE_CHECKING, cast
910

10-
from aiohttp import web
11+
from aiohttp import HttpVersion11, web
1112
from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
1213
from music_assistant_models.constants import PLAYER_CONTROL_FAKE, PLAYER_CONTROL_NONE
1314
from music_assistant_models.enums import (
@@ -580,6 +581,21 @@ async def _serve_ugp_stream(self, request: web.Request) -> web.StreamResponse:
580581
}
581582
resp = web.StreamResponse(status=200, reason="OK", headers=headers)
582583
http_profile = cast("str", self.config.get_value(CONF_HTTP_PROFILE, "chunked"))
584+
# prefer the child (protocol) player configuration
585+
if child_player_id:
586+
# player_id may be stale/invalid; fall back to the group profile
587+
with contextlib.suppress(KeyError):
588+
http_profile = await self.mass.config.get_player_config_value(
589+
child_player_id, CONF_HTTP_PROFILE, default=http_profile, return_type=str
590+
)
591+
if http_profile == "chunked" and request.version < HttpVersion11:
592+
# chunked encoding is not allowed on HTTP/1.0; fall back to
593+
# connection-close streaming to avoid raising in resp.prepare()
594+
self.logger.debug(
595+
"Disabling chunked encoding for UGP stream to HTTP/1.0 client %s",
596+
child_player_id or request.remote,
597+
)
598+
http_profile = "no_content_length"
583599
if http_profile == "forced_content_length":
584600
# some clients (notably older Chromecast firmware) refuse to play unless
585601
# they see a Content-Length header up front

0 commit comments

Comments
 (0)