/
/
/
1"""Constants for the AirPlay provider."""
2
3from __future__ import annotations
4
5from enum import IntEnum
6from typing import Final
7
8from music_assistant_models.config_entries import ConfigEntry
9from music_assistant_models.enums import ConfigEntryType, ContentType, PlayerFeature
10from music_assistant_models.media_items import AudioFormat
11
12from music_assistant.constants import INTERNAL_PCM_FORMAT
13
14DOMAIN = "airplay"
15
16
17class StreamingProtocol(IntEnum):
18 """AirPlay streaming protocol versions."""
19
20 RAOP = 1 # AirPlay 1 (RAOP)
21 AIRPLAY2 = 2 # AirPlay 2
22
23
24CACHE_CATEGORY_PREV_VOLUME: Final[int] = 1
25
26CONF_ENCRYPTION: Final[str] = "encryption"
27CONF_ALAC_ENCODE: Final[str] = "alac_encode"
28CONF_VOLUME_START: Final[str] = "volume_start"
29CONF_PASSWORD: Final[str] = "password"
30CONF_IGNORE_VOLUME: Final[str] = "ignore_volume"
31CONF_CREDENTIALS: Final[str] = "credentials"
32CONF_AIRPLAY_PROTOCOL: Final[str] = "airplay_protocol"
33
34AIRPLAY_DISCOVERY_TYPE: Final[str] = "_airplay._tcp.local."
35RAOP_DISCOVERY_TYPE: Final[str] = "_raop._tcp.local."
36DACP_DISCOVERY_TYPE: Final[str] = "_dacp._tcp.local."
37
38AIRPLAY_OUTPUT_BUFFER_DURATION_MS: Final[int] = (
39 2000 # Read ahead buffer for cliraop. Output buffer duration for cliap2.
40)
41AIRPLAY2_MIN_LOG_LEVEL: Final[int] = 3 # Min loglevel to ensure stderr output contains what we need
42AIRPLAY2_CONNECT_TIME_MS: Final[int] = 2500 # Time in ms to allow AirPlay2 device to connect
43RAOP_CONNECT_TIME_MS: Final[int] = 1000 # Time in ms to allow RAOP device to connect
44
45# Per-protocol credential storage keys
46CONF_RAOP_CREDENTIALS: Final[str] = "raop_credentials"
47CONF_AIRPLAY_CREDENTIALS: Final[str] = "airplay_credentials"
48
49# Legacy credential key (for migration)
50CONF_AP_CREDENTIALS: Final[str] = "ap_credentials"
51
52# Pairing action keys
53CONF_ACTION_START_PAIRING: Final[str] = "start_pairing"
54CONF_ACTION_FINISH_PAIRING: Final[str] = "finish_pairing"
55CONF_ACTION_RESET_PAIRING: Final[str] = "reset_pairing"
56CONF_PAIRING_PIN: Final[str] = "pairing_pin"
57CONF_ENABLE_LATE_JOIN: Final[str] = "enable_late_join"
58
59BACKOFF_TIME_LOWER_LIMIT: Final[int] = 15 # seconds
60BACKOFF_TIME_UPPER_LIMIT: Final[int] = 300 # Five minutes
61ENABLE_LATE_JOIN_DEFAULT: Final[bool] = True
62
63FALLBACK_VOLUME: Final[int] = 20
64
65AIRPLAY_FLOW_PCM_FORMAT = AudioFormat(
66 content_type=INTERNAL_PCM_FORMAT.content_type,
67 sample_rate=44100,
68 bit_depth=INTERNAL_PCM_FORMAT.bit_depth,
69)
70AIRPLAY_PCM_FORMAT = AudioFormat(
71 content_type=ContentType.from_bit_depth(16), sample_rate=44100, bit_depth=16
72)
73
74BROKEN_AIRPLAY_MODELS = (
75 # Samsung has been repeatedly being reported as having issues with AirPlay (raop and AP2)
76 ("Samsung", "*"),
77)
78
79AIRPLAY_2_DEFAULT_MODELS = (
80 # Models that are known to work better with AirPlay 2 protocol instead of RAOP
81 # These use the translated/friendly model names from get_model_info()
82 ("Ubiquiti Inc.", "*"),
83 ("LG Electronics", "*"),
84)
85
86PIN_REQUIRED = 0x8
87LEGACY_PAIRING_BIT = 0x200
88BROKEN_AIRPLAY_WARN = ConfigEntry(
89 key="BROKEN_AIRPLAY",
90 type=ConfigEntryType.ALERT,
91 default_value=None,
92 required=False,
93 label="This player is known to have broken AirPlay support. "
94 "Playback may fail or simply be silent. "
95 "There is no workaround for this issue at the moment. \n"
96 "If you already enforced AirPlay 2 on the player and it remains silent, "
97 "this is one of the known broken models. Only remedy is to nag the manufacturer for a fix.",
98)
99
100BASE_PLAYER_FEATURES: Final[set[PlayerFeature]] = {
101 PlayerFeature.PLAY_MEDIA,
102 PlayerFeature.SET_MEMBERS,
103 PlayerFeature.MULTI_DEVICE_DSP,
104 PlayerFeature.VOLUME_SET,
105}
106