async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" video = await self.hass.async_add_executor_job(getattr, self._camera, "last_video") if not video: error_msg = ( f"Video not found for {self._name}. " f"Is it older than {self._camera.min_days_vdo_cache} days?") _LOGGER.error(error_msg) return stream = CameraMjpeg(self._ffmpeg.binary) await stream.open_camera(video.video_url, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg.ffmpeg_stream_content_type, ) finally: try: await stream.close() except: _LOGGER.debug(f"problem with stream close for {self._name}")
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" from haffmpeg.camera import CameraMjpeg video = self._camera.last_video if not video: error_msg = "Video not found for {0}. Is it older than {1} days?".format( self._name, self._camera.min_days_vdo_cache) _LOGGER.error(error_msg) return ffmpeg_manager = self.hass.data[DATA_FFMPEG] stream = CameraMjpeg(ffmpeg_manager.binary, loop=self.hass.loop) await stream.open_camera(video.video_url, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, ffmpeg_manager.ffmpeg_stream_content_type, ) finally: await stream.close()
def __init__(self, hass, camera): """Initialize.""" super().__init__() self._camera = camera self._name = camera._friendly_name self._state = camera._state self._ssid = camera._ssid self._local_ip = camera._ip self._ssid = camera._ssid self._device_mac = camera._device_mac self._device_model = camera._device_model self._username = "******" self._password = "******" self.is_streaming = False self._ffmpeg = hass.data[DATA_FFMPEG] self._ffmpeg_arguments = DEFAULT_FFMPEG_ARGUMENTS self._ffmpeg_arguments_image = DEFAULT_FFMPEG_ARGUMENTS_IMAGE self._ffmpeg_image_frame = ImageFrame(self._ffmpeg.binary, loop=hass.loop) self._ffmpeg_stream = CameraMjpeg(self._ffmpeg.binary, loop=hass.loop) self._last_image = None self._last_image_url = None self._local_rtsp_port = camera._local_rtsp_port self._stream_url = f"rtsp://{self._username}:{self._password}@{self._local_ip}:{self._local_rtsp_port}/live" self.access_tokens = self.update_tokens()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" video = await self.hass.async_add_executor_job( getattr, self._camera, "last_video" ) if not video: error_msg = "Video not found for {0}. Is it older than {1} days?".format( self.name, self._camera.min_days_vdo_cache ) _LOGGER.error(error_msg) return stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop) await stream.open_camera(video.video_url, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): if not self.is_on: _LOGGER.debug('Miot camera: %s is off. %s', self.name, self._state_attrs) return url = await self.stream_source() if not url: _LOGGER.debug('Miot camera: %s url is empty. %s', self.name, self._state_attrs) return stream = CameraMjpeg(self._manager.binary) await stream.open_camera(url, extra_cmd=self._extra_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._manager.ffmpeg_stream_content_type, timeout=60, ) finally: try: await stream.close() except BrokenPipeError as exc: _LOGGER.error('Got BrokenPipeError when close stream: %s', url)
async def handle_async_mjpeg_stream(self, request): if not self.is_on: _LOGGER.debug('%s: camera is off. %s', self.name, self._state_attrs) return url = await self.stream_source() if not url: _LOGGER.debug('%s: stream source is empty. %s', self.name, self._state_attrs) return if '-i ' not in str(url): url = f'-i "{url}"' stream = CameraMjpeg(self._manager.binary) await stream.open_camera( f'{self._ffmpeg_options or ""} {url}'.strip(), extra_cmd=self._extra_arguments, ) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._manager.ffmpeg_stream_content_type, timeout=60, ) finally: try: await stream.close() except BrokenPipeError: _LOGGER.error('%s: Got BrokenPipeError when close stream: %s', self.name, url)
async def handle_async_mjpeg_stream(self, request): """Return an MJPEG stream.""" # The snapshot implementation is handled by the parent class if self._stream_source == STREAM_SOURCE_LIST['snapshot']: return await super().handle_async_mjpeg_stream(request) if self._stream_source == STREAM_SOURCE_LIST['mjpeg']: # stream an MJPEG image stream directly from the camera websession = async_get_clientsession(self.hass) streaming_url = self._camera.mjpeg_url(typeno=self._resolution) stream_coro = websession.get(streaming_url, auth=self._token, timeout=TIMEOUT) return await async_aiohttp_proxy_web(self.hass, request, stream_coro) # streaming via ffmpeg from haffmpeg.camera import CameraMjpeg streaming_url = self._camera.rtsp_url(typeno=self._resolution) stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop) await stream.open_camera(streaming_url, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg.ffmpeg_stream_content_type) finally: await stream.close()
def __init__(self, ffmpeg, device, coordinator): """Initialize.""" super().__init__(device, coordinator) Camera.__init__(self) self._async_unsub_dispatcher_connect = None self._ffmpeg = ffmpeg self._ffmpeg_arguments = DEFAULT_FFMPEG_ARGUMENTS self._ffmpeg_image_frame = ImageFrame(ffmpeg.binary) self._ffmpeg_stream = CameraMjpeg(ffmpeg.binary) self._last_image = None self._last_image_url = None self._stream_url = None
def __init__(self, hass, camera): """Initialize.""" super().__init__() self._async_unsub_dispatcher_connect = None self._camera = camera self._ffmpeg = hass.data[DATA_FFMPEG] self._ffmpeg_arguments = DEFAULT_FFMPEG_ARGUMENTS self._ffmpeg_image_frame = ImageFrame(self._ffmpeg.binary) self._ffmpeg_stream = CameraMjpeg(self._ffmpeg.binary) self._last_image = None self._last_image_url = None self._stream_url = None
async def handle_async_mjpeg_stream(self, request): """Return an MJPEG stream.""" assert self.hass is not None # The snapshot implementation is handled by the parent class if self._stream_source == "snapshot": _LOGGER.debug("Handling snapshot request") return await super().handle_async_mjpeg_stream(request) if not self.available: _LOGGER.warning( "Attempt to stream %s when %s camera is offline", self._stream_source, self.name, ) return None if self._stream_source == "mjpeg": # stream an MJPEG image stream directly from the camera _LOGGER.debug("Using mjpeg streaming") websession = async_get_clientsession(self.hass) streaming_url = self._api.mjpeg_url( typeno=self._resolution, channel=self._channel + 1 ) stream_coro = websession.get( streaming_url, auth=self._token, timeout=CAMERA_WEB_SESSION_TIMEOUT ) return await async_aiohttp_proxy_web(self.hass, request, stream_coro) # streaming via ffmpeg _LOGGER.debug("Using rtsp streaming") streaming_url = "-rtsp_transport tcp -i {}".format(self._rtsp_url) _LOGGER.debug("Using ffmpeg binary %s", self._ffmpeg.binary) stream = CameraMjpeg(self._ffmpeg.binary) await stream.open_camera(streaming_url, extra_cmd=self._ffmpeg_arguments) _LOGGER.debug( "Camera opened with url %s and arguments %s", streaming_url, self._ffmpeg_arguments, ) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): streaming_url = self.getStreamSource() stream = CameraMjpeg(self._ffmpeg.binary) await stream.open_camera(streaming_url) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" from haffmpeg.camera import CameraMjpeg stream = CameraMjpeg(self._manager.binary, loop=self.hass.loop) await stream.open_camera(self._input, extra_cmd=self._extra_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._manager.ffmpeg_stream_content_type) finally: await stream.close()
async def handle_async_mjpeg_stream( self, request: web.Request) -> web.StreamResponse: """Generate an HTTP MJPEG stream from the latest recorded activity.""" stream = CameraMjpeg(get_ffmpeg_manager(self.hass).binary) url = await self.coordinator.device.async_get_activity_video_url() await stream.open_camera(url, extra_cmd="-r 210") try: return await async_aiohttp_proxy_stream( self.hass, request, await stream.get_reader(), get_ffmpeg_manager(self.hass).ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" stream_source = await self.stream_source() stream = CameraMjpeg(self._manager.binary, loop=self._hass.loop) await stream.open_camera(stream_source) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self._hass, request, stream_reader, self._manager.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream( self, request: web.Request) -> web.StreamResponse: """Generate an HTTP MJPEG stream from the camera.""" stream = CameraMjpeg(self._manager.binary) await stream.open_camera(self._input, extra_cmd=self._extra_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._manager.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" if self._video_url is None: return stream = CameraMjpeg(self._ffmpeg_manager.binary) await stream.open_camera(self._video_url) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg_manager.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" from haffmpeg.camera import CameraMjpeg _LOGGER.debug("Handling mjpeg stream from camera '%s'", self._name) ffmpeg_manager = self.hass.data[DATA_FFMPEG] stream = CameraMjpeg(ffmpeg_manager.binary, loop=self.hass.loop) await stream.open_camera(self._input, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, ffmpeg_manager.ffmpeg_stream_content_type) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" if not self._is_on: return stream = CameraMjpeg(self._manager.binary) await stream.open_camera(self._last_url, extra_cmd=self._extra_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._manager.ffmpeg_stream_content_type, ) finally: await stream.close()
def __init__( self, coordinator: EufySecurityDataUpdateCoordinator, config_entry: ConfigEntry, device: Device, ) -> None: Camera.__init__(self) EufySecurityEntity.__init__(self, coordinator, config_entry, device) self.device.set_streaming_status_callback(self.set_is_streaming) self._attr_frontend_stream_type = STREAM_TYPE_HLS # camera image self.picture_bytes = None self.picture_url = None # p2p streaming self.start_stream_function = self.async_start_p2p_livestream self.stop_stream_function = self.async_stop_p2p_livestream # video generation using ffmpeg for p2p self.ffmpeg_binary = self.coordinator.hass.data[DATA_FFMPEG].binary self.ffmpeg = CameraMjpeg(self.ffmpeg_binary) self.default_codec = DEFAULT_CODEC self.is_ffmpeg_running = False # when HA started, p2p streaming was active, catch up with p2p streaming if self.device.is_p2p_streaming is True: async_call_later(self.coordinator.hass, 0, self.async_start_p2p_livestream) if self.coordinator.config.use_rtsp_server_addon is True: self.p2p_url = f"rtsp://{self.coordinator.config.rtsp_server_address}:{self.coordinator.config.rtsp_server_port}/{self.device.serial_number}" self.ffmpeg_output = f"-f rtsp -rtsp_transport tcp {self.p2p_url}" else: self.ffmpeg_output = f"{DOMAIN}-{self.device.serial_number}.m3u8" self.p2p_url = self.ffmpeg_output # for rtsp streaming if self.device.state.get("rtspStream", None) is not None: self.start_stream_function = self.async_start_rtsp_livestream self.stop_stream_function = self.async_stop_rtsp_livestream self.set_is_streaming()
async def handle_async_mjpeg_stream( self, request: web.Request) -> web.StreamResponse | None: """Return an MJPEG stream.""" assert self.hass is not None # The snapshot implementation is handled by the parent class if self._stream_source == "snapshot": return await super().handle_async_mjpeg_stream(request) if not self.available: _LOGGER.warning( "Attempt to stream %s when %s camera is offline", self._stream_source, self.name, ) return None if self._stream_source == "mjpeg": # stream an MJPEG image stream directly from the camera websession = async_get_clientsession(self.hass) streaming_url = self._api.mjpeg_url(typeno=self._resolution) stream_coro = websession.get(streaming_url, auth=self._token, timeout=CAMERA_WEB_SESSION_TIMEOUT) return await async_aiohttp_proxy_web(self.hass, request, stream_coro) # streaming via ffmpeg assert self._rtsp_url is not None streaming_url = self._rtsp_url stream = CameraMjpeg(self._ffmpeg.binary) await stream.open_camera(streaming_url, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" stream_source = "rtmp://{}:{}/bcs/channel0_{}.bcs?channel=0&stream=0&user={}&password={}".format( self._host, self._reolinkSession.rtmpport, self._stream, self._username, self._password) stream = CameraMjpeg(self._manager.binary, loop=self._hass.loop) await stream.open_camera(stream_source) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self._hass, request, stream_reader, self._manager.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request) -> Optional[StreamResponse]: """Generate an HTTP MJPEG stream from the camera.""" if not self._stream_url: return None ffmpeg_manager = self.hass.data[DATA_FFMPEG] stream = CameraMjpeg(ffmpeg_manager.binary, loop=self.hass.loop) await stream.open_camera(self._ffmpeg_input, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, ffmpeg_manager.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" if self._live_stream_session is None: return stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop) await stream.open_camera(self._live_stream_session.live_stream_url, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" from haffmpeg.camera import CameraMjpeg if not self._input: await self.hass.async_add_executor_job(self.obtain_input_uri) if not self._input: return None ffmpeg_manager = self.hass.data[DATA_FFMPEG] stream = CameraMjpeg(ffmpeg_manager.binary, loop=self.hass.loop) await stream.open_camera(self._input, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, ffmpeg_manager.ffmpeg_stream_content_type) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" from haffmpeg.camera import CameraMjpeg video = self._camera.last_video if not video: error_msg = \ 'Video not found for {0}. Is it older than {1} days?'.format( self.name, self._camera.min_days_vdo_cache) _LOGGER.error(error_msg) return stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop) await stream.open_camera(video.video_url, extra_cmd=self._ffmpeg_arguments) try: return await async_aiohttp_proxy_stream( self.hass, request, stream, 'multipart/x-mixed-replace;boundary=ffserver') finally: await stream.close()
async def handle_async_mjpeg_stream( self, request: Request) -> StreamResponse | None: """Generate an HTTP MJPEG stream from the camera.""" if self._live_stream_session is None: return None live_stream_url = await self.hass.async_add_executor_job( getattr, self._live_stream_session, "live_stream_url") stream = CameraMjpeg(self._ffmpeg.binary) await stream.open_camera(live_stream_url, extra_cmd=self._ffmpeg_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" _LOGGER.debug("Handling mjpeg stream from camera '%s'", self._name) stream_source = await self.stream_source() if not stream_source: return super().handle_async_mjpeg_stream(request) stream = CameraMjpeg(self._manager.binary) await stream.open_camera(stream_source, extra_cmd=self._extra_arguments) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._manager.ffmpeg_stream_content_type, ) finally: await stream.close()
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera's last activity.""" from haffmpeg.camera import CameraMjpeg last_activity = await self._camera.last_activity session_cookie = self._camera._logi._cache['cookie'] header = '"X-Logi-Auth: %s"' % (session_cookie) stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop) await stream.open_camera('-headers %s -i %s' % (header, last_activity.download_url)) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, self._ffmpeg.ffmpeg_stream_content_type) finally: try: await stream.close() except BrokenPipeError: return
async def handle_async_mjpeg_stream(self, request): """Generate an HTTP MJPEG stream from the camera.""" LOGGER.debug("Handling mjpeg stream from camera '%s'", self.device.name) ffmpeg_manager = self.hass.data[DATA_FFMPEG] stream = CameraMjpeg(ffmpeg_manager.binary) await stream.open_camera( self._stream_uri, extra_cmd=self.device.config_entry.options.get(CONF_EXTRA_ARGUMENTS), ) try: stream_reader = await stream.get_reader() return await async_aiohttp_proxy_stream( self.hass, request, stream_reader, ffmpeg_manager.ffmpeg_stream_content_type, ) finally: await stream.close()
def cli(ffmpeg, source, output, extra): """FFMPEG capture frame as image.""" loop = asyncio.get_event_loop() stream = CameraMjpeg(ffmpeg_bin=ffmpeg, loop=loop) async def read_stream(): """Read stream inside loop.""" await stream.open_camera(source, extra) reader = await stream.get_reader() try: while True: data = await reader.read(2048) print(data) except OSError: pass future = asyncio.ensure_future(read_stream()) try: loop.run_until_complete(future) finally: loop.call_soon_threadsafe(future.cancel) loop.run_until_complete(stream.close())