/
/
/
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. Default output buffer duration for cliap2.
40)
41AIRPLAY_OUTPUT_BUFFER_MIN_DURATION_MS: Final[int] = 250 # Minimum output buffer duration permitted.
42AIRPLAY2_MIN_LOG_LEVEL: Final[int] = 3 # Min loglevel to ensure stderr output contains what we need
43AIRPLAY2_CONNECT_TIME_MS: Final[int] = 3300 # Time in ms to allow AirPlay2 device to connect
44RAOP_CONNECT_TIME_MS: Final[int] = 1000 # Time in ms to allow RAOP device to connect
45
46# Per-protocol credential storage keys
47CONF_RAOP_CREDENTIALS: Final[str] = "raop_credentials"
48CONF_AIRPLAY_CREDENTIALS: Final[str] = "airplay_credentials"
49CONF_AIRPLAY_LATENCY: Final[str] = "airplay_latency"
50
51# Legacy credential key (for migration)
52CONF_AP_CREDENTIALS: Final[str] = "ap_credentials"
53
54# Pairing action keys
55CONF_ACTION_START_PAIRING: Final[str] = "start_pairing"
56CONF_ACTION_FINISH_PAIRING: Final[str] = "finish_pairing"
57CONF_ACTION_RESET_PAIRING: Final[str] = "reset_pairing"
58CONF_PAIRING_PIN: Final[str] = "pairing_pin"
59CONF_ENABLE_LATE_JOIN: Final[str] = "enable_late_join"
60
61BACKOFF_TIME_LOWER_LIMIT: Final[int] = 15 # seconds
62BACKOFF_TIME_UPPER_LIMIT: Final[int] = 300 # Five minutes
63ENABLE_LATE_JOIN_DEFAULT: Final[bool] = True
64
65FALLBACK_VOLUME: Final[int] = 20
66
67AIRPLAY_FLOW_PCM_FORMAT = AudioFormat(
68 content_type=INTERNAL_PCM_FORMAT.content_type,
69 sample_rate=44100,
70 bit_depth=INTERNAL_PCM_FORMAT.bit_depth,
71)
72AIRPLAY_PCM_FORMAT = AudioFormat(
73 content_type=ContentType.from_bit_depth(16), sample_rate=44100, bit_depth=16
74)
75
76BROKEN_AIRPLAY_MODELS = (
77 # Samsung has been repeatedly being reported as having issues with AirPlay (raop and AP2)
78 ("Samsung", "*"),
79)
80
81AIRPLAY_2_DEFAULT_MODELS = (
82 # Models that are known to work better with AirPlay 2 protocol instead of RAOP
83 # These use the translated/friendly model names from get_model_info()
84 ("Ubiquiti Inc.", "*"),
85 ("LG Electronics", "*"),
86)
87
88PIN_REQUIRED = 0x8
89LEGACY_PAIRING_BIT = 0x200
90BROKEN_AIRPLAY_WARN = ConfigEntry(
91 key="BROKEN_AIRPLAY",
92 type=ConfigEntryType.ALERT,
93 default_value=None,
94 required=False,
95 label="This player is known to have broken AirPlay support. "
96 "Playback may fail or simply be silent. "
97 "There is no workaround for this issue at the moment. \n"
98 "If you already enforced AirPlay 2 on the player and it remains silent, "
99 "this is one of the known broken models. Only remedy is to nag the manufacturer for a fix.",
100)
101
102BASE_PLAYER_FEATURES: Final[set[PlayerFeature]] = {
103 PlayerFeature.PLAY_MEDIA,
104 PlayerFeature.SET_MEMBERS,
105 PlayerFeature.MULTI_DEVICE_DSP,
106 PlayerFeature.VOLUME_SET,
107}
108