Home Assistant Unofficial Reference 2024.12.1
camera.py
Go to the documentation of this file.
1 """Support for Cameras with FFmpeg as decoder."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from aiohttp import web
8 from haffmpeg.camera import CameraMjpeg
9 from haffmpeg.tools import IMAGE_JPEG
10 import voluptuous as vol
11 
13  PLATFORM_SCHEMA as CAMERA_PLATFORM_SCHEMA,
14  Camera,
15  CameraEntityFeature,
16 )
17 from homeassistant.const import CONF_NAME
18 from homeassistant.core import HomeAssistant
19 from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream
21 from homeassistant.helpers.entity_platform import AddEntitiesCallback
22 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
23 
24 from . import (
25  CONF_EXTRA_ARGUMENTS,
26  CONF_INPUT,
27  DATA_FFMPEG,
28  FFmpegManager,
29  async_get_image,
30 )
31 
32 DEFAULT_NAME = "FFmpeg"
33 DEFAULT_ARGUMENTS = "-pred 1"
34 
35 PLATFORM_SCHEMA = CAMERA_PLATFORM_SCHEMA.extend(
36  {
37  vol.Required(CONF_INPUT): cv.string,
38  vol.Optional(CONF_EXTRA_ARGUMENTS, default=DEFAULT_ARGUMENTS): cv.string,
39  vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
40  }
41 )
42 
43 
45  hass: HomeAssistant,
46  config: ConfigType,
47  async_add_entities: AddEntitiesCallback,
48  discovery_info: DiscoveryInfoType | None = None,
49 ) -> None:
50  """Set up a FFmpeg camera."""
51  async_add_entities([FFmpegCamera(hass, config)])
52 
53 
55  """An implementation of an FFmpeg camera."""
56 
57  _attr_supported_features = CameraEntityFeature.STREAM
58 
59  def __init__(self, hass: HomeAssistant, config: dict[str, Any]) -> None:
60  """Initialize a FFmpeg camera."""
61  super().__init__()
62 
63  self._manager: FFmpegManager = hass.data[DATA_FFMPEG]
64  self._name: str = config[CONF_NAME]
65  self._input: str = config[CONF_INPUT]
66  self._extra_arguments: str = config[CONF_EXTRA_ARGUMENTS]
67 
68  async def stream_source(self) -> str:
69  """Return the stream source."""
70  return self._input.split(" ")[-1]
71 
72  async def async_camera_image(
73  self, width: int | None = None, height: int | None = None
74  ) -> bytes | None:
75  """Return a still image response from the camera."""
76  return await async_get_image(
77  self.hasshass,
78  self._input,
79  output_format=IMAGE_JPEG,
80  extra_cmd=self._extra_arguments,
81  )
82 
84  self, request: web.Request
85  ) -> web.StreamResponse:
86  """Generate an HTTP MJPEG stream from the camera."""
87 
88  stream = CameraMjpeg(self._manager.binary)
89  await stream.open_camera(self._input, extra_cmd=self._extra_arguments)
90 
91  try:
92  stream_reader = await stream.get_reader()
93  return await async_aiohttp_proxy_stream(
94  self.hasshass,
95  request,
96  stream_reader,
97  self._manager.ffmpeg_stream_content_type,
98  )
99  finally:
100  await stream.close()
101 
102  @property
103  def name(self) -> str:
104  """Return the name of this camera."""
105  return self._name
None __init__(self, HomeAssistant hass, dict[str, Any] config)
Definition: camera.py:59
web.StreamResponse handle_async_mjpeg_stream(self, web.Request request)
Definition: camera.py:85
bytes|None async_camera_image(self, int|None width=None, int|None height=None)
Definition: camera.py:74
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)
Definition: camera.py:49
bytes|None async_get_image(HomeAssistant hass, str input_source, str output_format=IMAGE_JPEG, str|None extra_cmd=None, int|None width=None, int|None height=None)
Definition: __init__.py:121
web.StreamResponse async_aiohttp_proxy_stream(HomeAssistant hass, web.BaseRequest request, aiohttp.StreamReader stream, str|None content_type, int buffer_size=102400, int timeout=10)