Home Assistant Unofficial Reference 2024.12.1
camera.py
Go to the documentation of this file.
1 """Support for Axis camera streaming."""
2 
3 from urllib.parse import urlencode
4 
5 from homeassistant.components.camera import CameraEntityFeature
6 from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging
7 from homeassistant.const import HTTP_DIGEST_AUTHENTICATION
8 from homeassistant.core import HomeAssistant
9 from homeassistant.helpers.dispatcher import async_dispatcher_connect
10 from homeassistant.helpers.entity_platform import AddEntitiesCallback
11 
12 from . import AxisConfigEntry
13 from .const import DEFAULT_STREAM_PROFILE, DEFAULT_VIDEO_SOURCE
14 from .entity import AxisEntity
15 from .hub import AxisHub
16 
17 
19  hass: HomeAssistant,
20  config_entry: AxisConfigEntry,
21  async_add_entities: AddEntitiesCallback,
22 ) -> None:
23  """Set up the Axis camera video stream."""
25 
26  hub = config_entry.runtime_data
27 
28  if (
29  not (prop := hub.api.vapix.params.property_handler.get("0"))
30  or not prop.image_format
31  ):
32  return
33 
35 
36 
37 class AxisCamera(AxisEntity, MjpegCamera):
38  """Representation of a Axis camera."""
39 
40  _attr_supported_features = CameraEntityFeature.STREAM
41 
42  _still_image_url: str
43  _mjpeg_url: str
44  _stream_source: str
45 
46  def __init__(self, hub: AxisHub) -> None:
47  """Initialize Axis Communications camera component."""
48  AxisEntity.__init__(self, hub)
49 
50  self._generate_sources_generate_sources()
51 
52  MjpegCamera.__init__(
53  self,
54  username=hub.config.username,
55  password=hub.config.password,
56  mjpeg_url=self.mjpeg_sourcemjpeg_source,
57  still_image_url=self.image_sourceimage_source,
58  authentication=HTTP_DIGEST_AUTHENTICATION,
59  verify_ssl=False,
60  unique_id=f"{hub.unique_id}-camera",
61  )
62 
63  async def async_added_to_hass(self) -> None:
64  """Subscribe camera events."""
65  self.async_on_removeasync_on_remove(
67  self.hasshass, self.hubhub.signal_new_address, self._generate_sources_generate_sources
68  )
69  )
70 
71  await super().async_added_to_hass()
72 
73  def _generate_sources(self) -> None:
74  """Generate sources.
75 
76  Additionally used when device change IP address.
77  """
78  proto = self.hubhub.config.protocol
79  host = self.hubhub.config.host
80  port = self.hubhub.config.port
81 
82  image_options = self.generate_optionsgenerate_options(skip_stream_profile=True)
83  self._still_image_url_still_image_url = (
84  f"{proto}://{host}:{port}/axis-cgi/jpg/image.cgi{image_options}"
85  )
86 
87  mjpeg_options = self.generate_optionsgenerate_options()
88  self._mjpeg_url_mjpeg_url = (
89  f"{proto}://{host}:{port}/axis-cgi/mjpg/video.cgi{mjpeg_options}"
90  )
91 
92  stream_options = self.generate_optionsgenerate_options(add_video_codec_h264=True)
93  self._stream_source_stream_source = (
94  f"rtsp://{self.hub.config.username}:{self.hub.config.password}"
95  f"@{self.hub.config.host}/axis-media/media.amp{stream_options}"
96  )
97 
98  self.hubhub.additional_diagnostics["camera_sources"] = {
99  "Image": self._still_image_url_still_image_url,
100  "MJPEG": self._mjpeg_url_mjpeg_url,
101  "Stream": (f"rtsp://user:pass@{host}/axis-media/media.amp{stream_options}"),
102  }
103 
104  @property
105  def image_source(self) -> str:
106  """Return still image URL for device."""
107  return self._still_image_url_still_image_url
108 
109  @property
110  def mjpeg_source(self) -> str:
111  """Return mjpeg URL for device."""
112  return self._mjpeg_url_mjpeg_url
113 
114  async def stream_source(self) -> str:
115  """Return the stream source."""
116  return self._stream_source_stream_source
117 
119  self, skip_stream_profile: bool = False, add_video_codec_h264: bool = False
120  ) -> str:
121  """Generate options for video stream."""
122  options_dict = {}
123 
124  if add_video_codec_h264:
125  options_dict["videocodec"] = "h264"
126 
127  if (
128  not skip_stream_profile
129  and self.hubhub.config.stream_profile != DEFAULT_STREAM_PROFILE
130  ):
131  options_dict["streamprofile"] = self.hubhub.config.stream_profile
132 
133  if self.hubhub.config.video_source != DEFAULT_VIDEO_SOURCE:
134  options_dict["camera"] = self.hubhub.config.video_source
135 
136  if not options_dict:
137  return ""
138  return f"?{urlencode(options_dict)}"
str generate_options(self, bool skip_stream_profile=False, bool add_video_codec_h264=False)
Definition: camera.py:120
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
None async_setup_entry(HomeAssistant hass, AxisConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: camera.py:22
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103