mirror of
https://github.com/home-assistant/core.git
synced 2025-07-11 23:37:18 +00:00
Add playback of autotrack lens to Reolink (#119829)
Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Franck Nijhof <frenck@frenck.nl>
This commit is contained in:
parent
a0f81cb401
commit
225e90c99e
@ -34,7 +34,15 @@ async def async_get_media_source(hass: HomeAssistant) -> ReolinkVODMediaSource:
|
|||||||
|
|
||||||
def res_name(stream: str) -> str:
|
def res_name(stream: str) -> str:
|
||||||
"""Return the user friendly name for a stream."""
|
"""Return the user friendly name for a stream."""
|
||||||
return "High res." if stream == "main" else "Low res."
|
match stream:
|
||||||
|
case "main":
|
||||||
|
return "High res."
|
||||||
|
case "autotrack_sub":
|
||||||
|
return "Autotrack low res."
|
||||||
|
case "autotrack_main":
|
||||||
|
return "Autotrack high res."
|
||||||
|
case _:
|
||||||
|
return "Low res."
|
||||||
|
|
||||||
|
|
||||||
class ReolinkVODMediaSource(MediaSource):
|
class ReolinkVODMediaSource(MediaSource):
|
||||||
@ -210,9 +218,6 @@ class ReolinkVODMediaSource(MediaSource):
|
|||||||
"playback only possible using sub stream",
|
"playback only possible using sub stream",
|
||||||
host.api.camera_name(channel),
|
host.api.camera_name(channel),
|
||||||
)
|
)
|
||||||
return await self._async_generate_camera_days(
|
|
||||||
config_entry_id, channel, "sub"
|
|
||||||
)
|
|
||||||
|
|
||||||
children = [
|
children = [
|
||||||
BrowseMediaSource(
|
BrowseMediaSource(
|
||||||
@ -224,16 +229,49 @@ class ReolinkVODMediaSource(MediaSource):
|
|||||||
can_play=False,
|
can_play=False,
|
||||||
can_expand=True,
|
can_expand=True,
|
||||||
),
|
),
|
||||||
BrowseMediaSource(
|
|
||||||
domain=DOMAIN,
|
|
||||||
identifier=f"RES|{config_entry_id}|{channel}|main",
|
|
||||||
media_class=MediaClass.CHANNEL,
|
|
||||||
media_content_type=MediaType.PLAYLIST,
|
|
||||||
title="High resolution",
|
|
||||||
can_play=False,
|
|
||||||
can_expand=True,
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
if main_enc != "h265":
|
||||||
|
children.append(
|
||||||
|
BrowseMediaSource(
|
||||||
|
domain=DOMAIN,
|
||||||
|
identifier=f"RES|{config_entry_id}|{channel}|main",
|
||||||
|
media_class=MediaClass.CHANNEL,
|
||||||
|
media_content_type=MediaType.PLAYLIST,
|
||||||
|
title="High resolution",
|
||||||
|
can_play=False,
|
||||||
|
can_expand=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if host.api.supported(channel, "autotrack_stream"):
|
||||||
|
children.append(
|
||||||
|
BrowseMediaSource(
|
||||||
|
domain=DOMAIN,
|
||||||
|
identifier=f"RES|{config_entry_id}|{channel}|autotrack_sub",
|
||||||
|
media_class=MediaClass.CHANNEL,
|
||||||
|
media_content_type=MediaType.PLAYLIST,
|
||||||
|
title="Autotrack low resolution",
|
||||||
|
can_play=False,
|
||||||
|
can_expand=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if main_enc != "h265":
|
||||||
|
children.append(
|
||||||
|
BrowseMediaSource(
|
||||||
|
domain=DOMAIN,
|
||||||
|
identifier=f"RES|{config_entry_id}|{channel}|autotrack_main",
|
||||||
|
media_class=MediaClass.CHANNEL,
|
||||||
|
media_content_type=MediaType.PLAYLIST,
|
||||||
|
title="Autotrack high resolution",
|
||||||
|
can_play=False,
|
||||||
|
can_expand=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(children) == 1:
|
||||||
|
return await self._async_generate_camera_days(
|
||||||
|
config_entry_id, channel, "sub"
|
||||||
|
)
|
||||||
|
|
||||||
return BrowseMediaSource(
|
return BrowseMediaSource(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
|
@ -156,11 +156,15 @@ async def test_browsing(
|
|||||||
browse_resolution_id = f"RESs|{entry_id}|{TEST_CHANNEL}"
|
browse_resolution_id = f"RESs|{entry_id}|{TEST_CHANNEL}"
|
||||||
browse_res_sub_id = f"RES|{entry_id}|{TEST_CHANNEL}|sub"
|
browse_res_sub_id = f"RES|{entry_id}|{TEST_CHANNEL}|sub"
|
||||||
browse_res_main_id = f"RES|{entry_id}|{TEST_CHANNEL}|main"
|
browse_res_main_id = f"RES|{entry_id}|{TEST_CHANNEL}|main"
|
||||||
|
browse_res_AT_sub_id = f"RES|{entry_id}|{TEST_CHANNEL}|autotrack_sub"
|
||||||
|
browse_res_AT_main_id = f"RES|{entry_id}|{TEST_CHANNEL}|autotrack_main"
|
||||||
assert browse.domain == DOMAIN
|
assert browse.domain == DOMAIN
|
||||||
assert browse.title == TEST_NVR_NAME
|
assert browse.title == TEST_NVR_NAME
|
||||||
assert browse.identifier == browse_resolution_id
|
assert browse.identifier == browse_resolution_id
|
||||||
assert browse.children[0].identifier == browse_res_sub_id
|
assert browse.children[0].identifier == browse_res_sub_id
|
||||||
assert browse.children[1].identifier == browse_res_main_id
|
assert browse.children[1].identifier == browse_res_main_id
|
||||||
|
assert browse.children[2].identifier == browse_res_AT_sub_id
|
||||||
|
assert browse.children[3].identifier == browse_res_AT_main_id
|
||||||
|
|
||||||
# browse camera recording days
|
# browse camera recording days
|
||||||
mock_status = MagicMock()
|
mock_status = MagicMock()
|
||||||
@ -169,6 +173,22 @@ async def test_browsing(
|
|||||||
mock_status.days = (TEST_DAY, TEST_DAY2)
|
mock_status.days = (TEST_DAY, TEST_DAY2)
|
||||||
reolink_connect.request_vod_files.return_value = ([mock_status], [])
|
reolink_connect.request_vod_files.return_value = ([mock_status], [])
|
||||||
|
|
||||||
|
browse = await async_browse_media(hass, f"{URI_SCHEME}{DOMAIN}/{browse_res_sub_id}")
|
||||||
|
assert browse.domain == DOMAIN
|
||||||
|
assert browse.title == f"{TEST_NVR_NAME} Low res."
|
||||||
|
|
||||||
|
browse = await async_browse_media(
|
||||||
|
hass, f"{URI_SCHEME}{DOMAIN}/{browse_res_AT_sub_id}"
|
||||||
|
)
|
||||||
|
assert browse.domain == DOMAIN
|
||||||
|
assert browse.title == f"{TEST_NVR_NAME} Autotrack low res."
|
||||||
|
|
||||||
|
browse = await async_browse_media(
|
||||||
|
hass, f"{URI_SCHEME}{DOMAIN}/{browse_res_AT_main_id}"
|
||||||
|
)
|
||||||
|
assert browse.domain == DOMAIN
|
||||||
|
assert browse.title == f"{TEST_NVR_NAME} Autotrack high res."
|
||||||
|
|
||||||
browse = await async_browse_media(
|
browse = await async_browse_media(
|
||||||
hass, f"{URI_SCHEME}{DOMAIN}/{browse_res_main_id}"
|
hass, f"{URI_SCHEME}{DOMAIN}/{browse_res_main_id}"
|
||||||
)
|
)
|
||||||
@ -225,6 +245,7 @@ async def test_browsing_unsupported_encoding(
|
|||||||
reolink_connect.request_vod_files.return_value = ([mock_status], [])
|
reolink_connect.request_vod_files.return_value = ([mock_status], [])
|
||||||
reolink_connect.time.return_value = None
|
reolink_connect.time.return_value = None
|
||||||
reolink_connect.get_encoding.return_value = "h265"
|
reolink_connect.get_encoding.return_value = "h265"
|
||||||
|
reolink_connect.supported.return_value = False
|
||||||
|
|
||||||
browse = await async_browse_media(hass, f"{URI_SCHEME}{DOMAIN}/{browse_root_id}")
|
browse = await async_browse_media(hass, f"{URI_SCHEME}{DOMAIN}/{browse_root_id}")
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user