/
/
/
1"""Constants for Chromecast Player provider."""
2
3from __future__ import annotations
4
5from music_assistant_models.config_entries import ConfigEntry
6from music_assistant_models.enums import ConfigEntryType
7
8from music_assistant.constants import (
9 CONF_ENTRY_FLOW_MODE,
10 CONF_ENTRY_HTTP_PROFILE_DEFAULT_3,
11 CONF_ENTRY_OUTPUT_CODEC,
12 CONF_ENTRY_PREFER_WAV_FOR_LIVE_SOURCES_DEFAULT_ENABLED,
13 create_sample_rates_config_entry,
14)
15
16MASS_APP_ID = "C35B0678"
17APP_MEDIA_RECEIVER = "CC1AD845"
18SENDSPIN_CAST_APP_ID = "DD107DDB"
19SENDSPIN_CAST_NAMESPACE = "urn:x-cast:sendspin"
20CONF_USE_MASS_APP = "use_mass_app"
21DASHBOARD_NAMESPACE = "urn:x-cast:io.music-assistant.cast"
22
23# Seconds to wait for a Cast receiver to acknowledge an app launch.
24APP_LAUNCH_TIMEOUT = 30.0
25
26# keepalive media the cast receiver plays while showing a dashboard
27DASHBOARD_KEEPALIVE_SUFFIXES = ("/dashboard-keepalive.mp4", "/keepalive.png")
28
29# Interval (seconds) before an unavailable player is re-evaluated as a possible
30# passive multichannel endpoint that should be removed from the setup.
31MULTICHANNEL_RECHECK_INTERVAL = 600
32
33# Devices known to not work with the Sendspin Cast bridge.
34# Tuple of (manufacturer, model) where "*" is a wildcard.
35# These devices will not get a Sendspin bridge, allowing other protocols
36# (e.g. AirPlay bridge) to handle them instead.
37SENDSPIN_CAST_BLOCKLIST: set[tuple[str, str]] = {
38 ("Harman Luxury Audio", "*"),
39 ("*", "HK OMNI ADAPT+AMP"),
40}
41
42CAST_PLAYER_CONFIG_ENTRIES = (
43 CONF_ENTRY_OUTPUT_CODEC,
44 CONF_ENTRY_PREFER_WAV_FOR_LIVE_SOURCES_DEFAULT_ENABLED,
45 CONF_ENTRY_HTTP_PROFILE_DEFAULT_3,
46 # enable flow mode by default as cast devices handle a continuous
47 # flow stream more reliably than enqueueing individual tracks
48 ConfigEntry.from_dict({**CONF_ENTRY_FLOW_MODE.to_dict(), "default_value": True}),
49 ConfigEntry(
50 key=CONF_USE_MASS_APP,
51 type=ConfigEntryType.BOOLEAN,
52 default_value=True,
53 advanced=True,
54 ),
55)
56
57# originally/officially cast supports 96k sample rate (even for groups)
58# but it seems a (recent?) update broke this ?!
59# For now only set safe default values and let the user try out higher values
60CONF_ENTRY_SAMPLE_RATES_CAST = create_sample_rates_config_entry(
61 max_sample_rate=192000,
62 max_bit_depth=24,
63 safe_max_sample_rate=48000,
64 safe_max_bit_depth=16,
65)
66CONF_ENTRY_SAMPLE_RATES_CAST_GROUP = create_sample_rates_config_entry(
67 max_sample_rate=96000,
68 max_bit_depth=24,
69 safe_max_sample_rate=48000,
70 safe_max_bit_depth=16,
71)
72
73# Measured defaults for known Cast models.
74CAST_MODEL_STATIC_DELAY: dict[tuple[str, str], int] = {
75 ("Google Inc.", "Google Home Mini"): 330,
76 ("Google Inc.", "Google Nest Mini"): 427,
77 ("Google Inc.", "Chromecast Audio"): 335,
78 ("Google Inc.", "Google Nest Hub"): 188,
79}
80CAST_FALLBACK_STATIC_DELAY = 330
81
82
83def get_cast_model_static_delay(manufacturer: str, model: str) -> int:
84 """
85 Look up the default static delay for a Cast device model.
86
87 :param manufacturer: Device manufacturer (e.g., "Google Inc.").
88 :param model: Device model name (e.g., "Google Nest Mini").
89 """
90 return CAST_MODEL_STATIC_DELAY.get((manufacturer, model), CAST_FALLBACK_STATIC_DELAY)
91