mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Route non-TTS media through ESPHome ffmpeg proxy (#126287)
* Route non-TTS media through proxy * Use media_id_source
This commit is contained in:
parent
e8d5ebef7e
commit
123b6b687e
@ -14,6 +14,7 @@ import wave
|
|||||||
|
|
||||||
from aioesphomeapi import (
|
from aioesphomeapi import (
|
||||||
MediaPlayerFormatPurpose,
|
MediaPlayerFormatPurpose,
|
||||||
|
MediaPlayerSupportedFormat,
|
||||||
VoiceAssistantAnnounceFinished,
|
VoiceAssistantAnnounceFinished,
|
||||||
VoiceAssistantAudioSettings,
|
VoiceAssistantAudioSettings,
|
||||||
VoiceAssistantCommandFlag,
|
VoiceAssistantCommandFlag,
|
||||||
@ -44,6 +45,7 @@ from .const import DOMAIN
|
|||||||
from .entity import EsphomeAssistEntity
|
from .entity import EsphomeAssistEntity
|
||||||
from .entry_data import ESPHomeConfigEntry, RuntimeEntryData
|
from .entry_data import ESPHomeConfigEntry, RuntimeEntryData
|
||||||
from .enum_mapper import EsphomeEnumMapper
|
from .enum_mapper import EsphomeEnumMapper
|
||||||
|
from .ffmpeg_proxy import async_create_proxy_url
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -325,8 +327,34 @@ class EsphomeAssistSatellite(
|
|||||||
announcement.message,
|
announcement.message,
|
||||||
announcement.media_id,
|
announcement.media_id,
|
||||||
)
|
)
|
||||||
|
media_id = announcement.media_id
|
||||||
|
if announcement.media_id_source != "tts":
|
||||||
|
# Route non-TTS media through the proxy
|
||||||
|
format_to_use: MediaPlayerSupportedFormat | None = None
|
||||||
|
for supported_format in chain(
|
||||||
|
*self.entry_data.media_player_formats.values()
|
||||||
|
):
|
||||||
|
if supported_format.purpose == MediaPlayerFormatPurpose.ANNOUNCEMENT:
|
||||||
|
format_to_use = supported_format
|
||||||
|
break
|
||||||
|
|
||||||
|
if format_to_use is not None:
|
||||||
|
assert (self.registry_entry is not None) and (
|
||||||
|
self.registry_entry.device_id is not None
|
||||||
|
)
|
||||||
|
proxy_url = async_create_proxy_url(
|
||||||
|
self.hass,
|
||||||
|
self.registry_entry.device_id,
|
||||||
|
media_id,
|
||||||
|
media_format=format_to_use.format,
|
||||||
|
rate=format_to_use.sample_rate or None,
|
||||||
|
channels=format_to_use.num_channels or None,
|
||||||
|
width=format_to_use.sample_bytes or None,
|
||||||
|
)
|
||||||
|
media_id = async_process_play_media_url(self.hass, proxy_url)
|
||||||
|
|
||||||
await self.cli.send_voice_assistant_announcement_await_response(
|
await self.cli.send_voice_assistant_announcement_await_response(
|
||||||
announcement.media_id, _ANNOUNCEMENT_TIMEOUT_SEC, announcement.message
|
media_id, _ANNOUNCEMENT_TIMEOUT_SEC, announcement.message
|
||||||
)
|
)
|
||||||
|
|
||||||
async def handle_pipeline_start(
|
async def handle_pipeline_start(
|
||||||
|
@ -1222,11 +1222,29 @@ async def test_announce_media_id(
|
|||||||
[APIClient, list[EntityInfo], list[UserService], list[EntityState]],
|
[APIClient, list[EntityInfo], list[UserService], list[EntityState]],
|
||||||
Awaitable[MockESPHomeDevice],
|
Awaitable[MockESPHomeDevice],
|
||||||
],
|
],
|
||||||
|
device_registry: dr.DeviceRegistry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test announcement with media id."""
|
"""Test announcement with media id."""
|
||||||
mock_device: MockESPHomeDevice = await mock_esphome_device(
|
mock_device: MockESPHomeDevice = await mock_esphome_device(
|
||||||
mock_client=mock_client,
|
mock_client=mock_client,
|
||||||
entity_info=[],
|
entity_info=[
|
||||||
|
MediaPlayerInfo(
|
||||||
|
object_id="mymedia_player",
|
||||||
|
key=1,
|
||||||
|
name="my media_player",
|
||||||
|
unique_id="my_media_player",
|
||||||
|
supports_pause=True,
|
||||||
|
supported_formats=[
|
||||||
|
MediaPlayerSupportedFormat(
|
||||||
|
format="flac",
|
||||||
|
sample_rate=48000,
|
||||||
|
num_channels=2,
|
||||||
|
purpose=MediaPlayerFormatPurpose.ANNOUNCEMENT,
|
||||||
|
sample_bytes=2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
user_service=[],
|
user_service=[],
|
||||||
states=[],
|
states=[],
|
||||||
device_info={
|
device_info={
|
||||||
@ -1238,6 +1256,10 @@ async def test_announce_media_id(
|
|||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
dev = device_registry.async_get_device(
|
||||||
|
connections={(dr.CONNECTION_NETWORK_MAC, mock_device.entry.unique_id)}
|
||||||
|
)
|
||||||
|
|
||||||
satellite = get_satellite_entity(hass, mock_device.device_info.mac_address)
|
satellite = get_satellite_entity(hass, mock_device.device_info.mac_address)
|
||||||
assert satellite is not None
|
assert satellite is not None
|
||||||
|
|
||||||
@ -1247,7 +1269,7 @@ async def test_announce_media_id(
|
|||||||
media_id: str, timeout: float, text: str
|
media_id: str, timeout: float, text: str
|
||||||
):
|
):
|
||||||
assert satellite.state == AssistSatelliteState.RESPONDING
|
assert satellite.state == AssistSatelliteState.RESPONDING
|
||||||
assert media_id == "https://www.home-assistant.io/resolved.mp3"
|
assert media_id == "https://www.home-assistant.io/proxied.flac"
|
||||||
|
|
||||||
done.set()
|
done.set()
|
||||||
|
|
||||||
@ -1257,6 +1279,10 @@ async def test_announce_media_id(
|
|||||||
"send_voice_assistant_announcement_await_response",
|
"send_voice_assistant_announcement_await_response",
|
||||||
new=send_voice_assistant_announcement_await_response,
|
new=send_voice_assistant_announcement_await_response,
|
||||||
),
|
),
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.esphome.assist_satellite.async_create_proxy_url",
|
||||||
|
return_value="https://www.home-assistant.io/proxied.flac",
|
||||||
|
) as mock_async_create_proxy_url,
|
||||||
):
|
):
|
||||||
async with asyncio.timeout(1):
|
async with asyncio.timeout(1):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
@ -1271,6 +1297,16 @@ async def test_announce_media_id(
|
|||||||
await done.wait()
|
await done.wait()
|
||||||
assert satellite.state == AssistSatelliteState.LISTENING_WAKE_WORD
|
assert satellite.state == AssistSatelliteState.LISTENING_WAKE_WORD
|
||||||
|
|
||||||
|
mock_async_create_proxy_url.assert_called_once_with(
|
||||||
|
hass,
|
||||||
|
dev.id,
|
||||||
|
"https://www.home-assistant.io/resolved.mp3",
|
||||||
|
media_format="flac",
|
||||||
|
rate=48000,
|
||||||
|
channels=2,
|
||||||
|
width=2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_satellite_unloaded_on_disconnect(
|
async def test_satellite_unloaded_on_disconnect(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user