Update nest media player device thumbnails (#64738)
parent
c06a32cdb4
commit
a5fb60fd3a
|
@ -377,9 +377,15 @@ class NestMediaSource(MediaSource):
|
|||
browse_root = _browse_root()
|
||||
browse_root.children = []
|
||||
for device_id, child_device in devices.items():
|
||||
browse_root.children.append(
|
||||
_browse_device(MediaId(device_id), child_device)
|
||||
)
|
||||
browse_device = _browse_device(MediaId(device_id), child_device)
|
||||
if last_event_id := await _async_get_recent_event_id(
|
||||
MediaId(device_id), child_device
|
||||
):
|
||||
browse_device.thumbnail = EVENT_THUMBNAIL_URL_FORMAT.format(
|
||||
device_id=last_event_id.device_id,
|
||||
event_token=last_event_id.event_token,
|
||||
)
|
||||
browse_root.children.append(browse_device)
|
||||
return browse_root
|
||||
|
||||
# Browse either a device or events within a device
|
||||
|
@ -399,11 +405,9 @@ class NestMediaSource(MediaSource):
|
|||
browse_device.children = []
|
||||
for clip in clips.values():
|
||||
event_id = MediaId(media_id.device_id, clip.event_token)
|
||||
browse_event = _browse_clip_preview(event_id, device, clip)
|
||||
browse_device.children.append(browse_event)
|
||||
# Use thumbnail for first event in the list as the device thumbnail
|
||||
if browse_device.thumbnail is None:
|
||||
browse_device.thumbnail = browse_event.thumbnail
|
||||
browse_device.children.append(
|
||||
_browse_clip_preview(event_id, device, clip)
|
||||
)
|
||||
return browse_device
|
||||
|
||||
# Browse a specific event
|
||||
|
@ -421,11 +425,9 @@ class NestMediaSource(MediaSource):
|
|||
browse_device.children = []
|
||||
for image in images.values():
|
||||
event_id = MediaId(media_id.device_id, image.event_token)
|
||||
browse_event = _browse_image_event(event_id, device, image)
|
||||
browse_device.children.append(browse_event)
|
||||
# Use thumbnail for first event in the list as the device thumbnail
|
||||
if browse_device.thumbnail is None:
|
||||
browse_device.thumbnail = browse_event.thumbnail
|
||||
browse_device.children.append(
|
||||
_browse_image_event(event_id, device, image)
|
||||
)
|
||||
return browse_device
|
||||
|
||||
# Browse a specific event
|
||||
|
@ -470,6 +472,21 @@ def _browse_root() -> BrowseMediaSource:
|
|||
)
|
||||
|
||||
|
||||
async def _async_get_recent_event_id(
|
||||
device_id: MediaId, device: Device
|
||||
) -> MediaId | None:
|
||||
"""Return thumbnail for most recent device event."""
|
||||
if CameraClipPreviewTrait.NAME in device.traits:
|
||||
clips = await device.event_media_manager.async_clip_preview_sessions()
|
||||
if not clips:
|
||||
return None
|
||||
return MediaId(device_id.device_id, next(iter(clips)).event_token)
|
||||
images = await device.event_media_manager.async_image_sessions()
|
||||
if not images:
|
||||
return None
|
||||
return MediaId(device_id.device_id, next(iter(images)).event_token)
|
||||
|
||||
|
||||
def _browse_device(device_id: MediaId, device: Device) -> BrowseMediaSource:
|
||||
"""Return details for the specified device."""
|
||||
device_info = NestDeviceInfo(device)
|
||||
|
|
|
@ -104,7 +104,6 @@ def mp4() -> io.BytesIO:
|
|||
stream.width = 480
|
||||
stream.height = 320
|
||||
stream.pix_fmt = "yuv420p"
|
||||
# stream.options.update({"g": str(fps), "keyint_min": str(fps)})
|
||||
|
||||
for frame_i in range(total_frames):
|
||||
img = frame_image_data(frame_i, total_frames)
|
||||
|
@ -207,9 +206,10 @@ async def test_no_eligible_devices(hass, auth):
|
|||
assert not browse.children
|
||||
|
||||
|
||||
async def test_supported_device(hass, auth):
|
||||
@pytest.mark.parametrize("traits", [CAMERA_TRAITS, BATTERY_CAMERA_TRAITS])
|
||||
async def test_supported_device(hass, auth, traits):
|
||||
"""Test a media source with a supported camera."""
|
||||
await async_setup_devices(hass, auth, CAMERA_DEVICE_TYPE, CAMERA_TRAITS)
|
||||
await async_setup_devices(hass, auth, CAMERA_DEVICE_TYPE, traits)
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
camera = hass.states.get("camera.front")
|
||||
|
@ -770,6 +770,17 @@ async def test_camera_event_clip_preview(hass, auth, hass_client, mp4):
|
|||
assert received_event.data["type"] == "camera_motion"
|
||||
event_identifier = received_event.data["nest_event_id"]
|
||||
|
||||
# List devices
|
||||
browse = await media_source.async_browse_media(hass, f"{const.URI_SCHEME}{DOMAIN}")
|
||||
assert browse.domain == DOMAIN
|
||||
assert len(browse.children) == 1
|
||||
assert browse.children[0].domain == DOMAIN
|
||||
assert browse.children[0].identifier == device.id
|
||||
assert browse.children[0].title == "Front: Recent Events"
|
||||
assert (
|
||||
browse.children[0].thumbnail
|
||||
== f"/api/nest/event_media/{device.id}/{event_identifier}/thumbnail"
|
||||
)
|
||||
# Browse to the device
|
||||
browse = await media_source.async_browse_media(
|
||||
hass, f"{const.URI_SCHEME}{DOMAIN}/{device.id}"
|
||||
|
@ -778,10 +789,7 @@ async def test_camera_event_clip_preview(hass, auth, hass_client, mp4):
|
|||
assert browse.identifier == device.id
|
||||
assert browse.title == "Front: Recent Events"
|
||||
assert browse.can_expand
|
||||
assert (
|
||||
browse.thumbnail
|
||||
== f"/api/nest/event_media/{device.id}/{event_identifier}/thumbnail"
|
||||
)
|
||||
assert not browse.thumbnail
|
||||
# The device expands recent events
|
||||
assert len(browse.children) == 1
|
||||
assert browse.children[0].domain == DOMAIN
|
||||
|
@ -1404,12 +1412,22 @@ async def test_camera_image_resize(hass, auth, hass_client):
|
|||
assert contents == IMAGE_BYTES_FROM_EVENT
|
||||
|
||||
# The event thumbnail is used for the device thumbnail
|
||||
browse = await media_source.async_browse_media(hass, f"{const.URI_SCHEME}{DOMAIN}")
|
||||
assert browse.domain == DOMAIN
|
||||
assert len(browse.children) == 1
|
||||
assert browse.children[0].identifier == device.id
|
||||
assert browse.children[0].title == "Front: Recent Events"
|
||||
assert (
|
||||
browse.children[0].thumbnail
|
||||
== f"/api/nest/event_media/{device.id}/{event_identifier}/thumbnail"
|
||||
)
|
||||
|
||||
# Browse to device. No thumbnail is needed for the device on the device page
|
||||
browse = await media_source.async_browse_media(
|
||||
hass, f"{const.URI_SCHEME}{DOMAIN}/{device.id}"
|
||||
)
|
||||
assert browse.domain == DOMAIN
|
||||
assert browse.identifier == device.id
|
||||
assert (
|
||||
browse.thumbnail
|
||||
== f"/api/nest/event_media/{device.id}/{event_identifier}/thumbnail"
|
||||
)
|
||||
assert browse.title == "Front: Recent Events"
|
||||
assert not browse.thumbnail
|
||||
assert len(browse.children) == 1
|
||||
|
|
Loading…
Reference in New Issue