-
-
Notifications
You must be signed in to change notification settings - Fork 37.2k
Add get_image method to Stream #61918
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
862b14d
d477666
d90ef18
1e6935e
4df3d9d
acb29b5
8ec4b60
26b301c
7dfd7b3
43b2464
357a240
510c664
6229c87
dddfd48
f549f31
bbe0982
5519323
fb9b8fe
aec32bc
b2f17a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,7 +23,7 @@ | |
| import av | ||
| import pytest | ||
|
|
||
| from homeassistant.components.stream import Stream, create_stream | ||
| from homeassistant.components.stream import KeyFrameConverter, Stream, create_stream | ||
| from homeassistant.components.stream.const import ( | ||
| ATTR_SETTINGS, | ||
| CONF_LL_HLS, | ||
|
|
@@ -45,6 +45,7 @@ | |
| ) | ||
| from homeassistant.setup import async_setup_component | ||
|
|
||
| from tests.components.camera.common import EMPTY_8_6_JPEG, mock_turbo_jpeg | ||
| from tests.components.stream.common import generate_h264_video, generate_h265_video | ||
| from tests.components.stream.test_ll_hls import TEST_PART_DURATION | ||
|
|
||
|
|
@@ -97,6 +98,17 @@ class FakeCodec: | |
|
|
||
| self.codec = FakeCodec() | ||
|
|
||
| class FakeCodecContext: | ||
| name = "h264" | ||
| extradata = None | ||
|
|
||
| self.codec_context = FakeCodecContext() | ||
|
|
||
| @property | ||
| def type(self): | ||
| """Return packet type.""" | ||
| return "video" if self.name == VIDEO_STREAM_FORMAT else "audio" | ||
|
|
||
| def __str__(self) -> str: | ||
| """Return a stream name for debugging.""" | ||
| return f"FakePyAvStream<{self.name}, {self.time_base}>" | ||
|
|
@@ -195,6 +207,7 @@ def add_stream(self, template=None): | |
| class FakeAvOutputStream: | ||
| def __init__(self, capture_packets): | ||
| self.capture_packets = capture_packets | ||
| self.type = "ignored-type" | ||
|
|
||
| def close(self): | ||
| return | ||
|
|
@@ -258,7 +271,9 @@ def open(self, stream_source, *args, **kwargs): | |
| def run_worker(hass, stream, stream_source): | ||
| """Run the stream worker under test.""" | ||
| stream_state = StreamState(hass, stream.outputs) | ||
| stream_worker(stream_source, {}, stream_state, threading.Event()) | ||
| stream_worker( | ||
| stream_source, {}, stream_state, KeyFrameConverter(hass), threading.Event() | ||
| ) | ||
|
|
||
|
|
||
| async def async_decode_stream(hass, packets, py_av=None): | ||
|
|
@@ -854,3 +869,29 @@ async def test_h265_video_is_hvc1(hass, record_worker_sync): | |
| await record_worker_sync.join() | ||
|
|
||
| stream.stop() | ||
|
|
||
|
|
||
| async def test_get_image(hass, record_worker_sync): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to add some test coverage for the case with multiple tasks asking for image thumbnail to be produced? (I assume that is a case that can happen)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can add this after we figure out the other stuff.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As the code stands right now, there is an asyncio lock around the call to |
||
| """Test that the has_keyframe metadata matches the media.""" | ||
| await async_setup_component(hass, "stream", {"stream": {}}) | ||
|
|
||
| source = generate_h264_video() | ||
|
|
||
| # Since libjpeg-turbo is not installed on the CI runner, we use a mock | ||
| with patch( | ||
| "homeassistant.components.camera.img_util.TurboJPEGSingleton" | ||
| ) as mock_turbo_jpeg_singleton: | ||
| mock_turbo_jpeg_singleton.instance.return_value = mock_turbo_jpeg() | ||
| stream = create_stream(hass, source, {}) | ||
|
|
||
| # use record_worker_sync to grab output segments | ||
| with patch.object(hass.config, "is_allowed_path", return_value=True): | ||
| await stream.async_record("/example/path") | ||
|
|
||
| assert stream._keyframe_converter._image is None | ||
|
|
||
| await record_worker_sync.join() | ||
|
|
||
| assert await stream.get_image() == EMPTY_8_6_JPEG | ||
|
|
||
| stream.stop() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a problem to make
cameraadependenciesforstream? It seems like they would be loading it anywaysThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also a circular import problem between the two components because camera also imports things from stream. The easiest way to avoid this is to rejig the imports (including the conditional ones) to avoid importing individual classes/functions from each other and instead importing the whole modules (ie avoid using
from x import yand just usingimport x), but the former seems to be preferred in the HA codebase and the existingstreamandcameracode follow this. If we want to make those changes, I can do that in this PR or another one.