Update nest media player device thumbnails (#64738)

pull/58485/head^2
Allen Porter 2022-01-22 23:46:00 -08:00 committed by GitHub
parent c06a32cdb4
commit a5fb60fd3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 24 deletions

View File

@ -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)

View File

@ -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