mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Add ffmpeg camera platform support (#2755)
This commit is contained in:
parent
991e292d7e
commit
98c77dc08f
@ -100,6 +100,7 @@ omit =
|
|||||||
homeassistant/components/binary_sensor/rest.py
|
homeassistant/components/binary_sensor/rest.py
|
||||||
homeassistant/components/browser.py
|
homeassistant/components/browser.py
|
||||||
homeassistant/components/camera/bloomsky.py
|
homeassistant/components/camera/bloomsky.py
|
||||||
|
homeassistant/components/camera/ffmpeg.py
|
||||||
homeassistant/components/camera/foscam.py
|
homeassistant/components/camera/foscam.py
|
||||||
homeassistant/components/camera/generic.py
|
homeassistant/components/camera/generic.py
|
||||||
homeassistant/components/camera/mjpeg.py
|
homeassistant/components/camera/mjpeg.py
|
||||||
|
75
homeassistant/components/camera/ffmpeg.py
Normal file
75
homeassistant/components/camera/ffmpeg.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
"""
|
||||||
|
Support for Cameras with FFmpeg as decoder.
|
||||||
|
|
||||||
|
For more details about this platform, please refer to the documentation at
|
||||||
|
https://home-assistant.io/components/camera.ffmpeg/
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.camera import Camera
|
||||||
|
from homeassistant.components.camera.mjpeg import extract_image_from_mjpeg
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.const import CONF_NAME, CONF_PLATFORM
|
||||||
|
|
||||||
|
REQUIREMENTS = ["ha-ffmpeg==0.4"]
|
||||||
|
|
||||||
|
CONF_INPUT = 'input'
|
||||||
|
CONF_FFMPEG_BIN = 'ffmpeg_bin'
|
||||||
|
CONF_EXTRA_ARGUMENTS = 'extra_arguments'
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = vol.Schema({
|
||||||
|
vol.Required(CONF_PLATFORM): "ffmpeg",
|
||||||
|
vol.Optional(CONF_NAME, default="FFmpeg"): cv.string,
|
||||||
|
vol.Required(CONF_INPUT): cv.string,
|
||||||
|
vol.Optional(CONF_FFMPEG_BIN, default="ffmpeg"): cv.string,
|
||||||
|
vol.Optional(CONF_EXTRA_ARGUMENTS): cv.string,
|
||||||
|
})
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||||
|
"""Setup a FFmpeg Camera."""
|
||||||
|
add_devices_callback([FFmpegCamera(config)])
|
||||||
|
|
||||||
|
|
||||||
|
class FFmpegCamera(Camera):
|
||||||
|
"""An implementation of an IP camera that is reachable over a URL."""
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
"""Initialize a FFmpeg camera."""
|
||||||
|
super().__init__()
|
||||||
|
self._name = config.get(CONF_NAME)
|
||||||
|
self._input = config.get(CONF_INPUT)
|
||||||
|
self._extra_arguments = config.get(CONF_EXTRA_ARGUMENTS)
|
||||||
|
self._ffmpeg_bin = config.get(CONF_FFMPEG_BIN)
|
||||||
|
|
||||||
|
def _ffmpeg_stream(self):
|
||||||
|
"""Return a FFmpeg process object."""
|
||||||
|
from haffmpeg import CameraMjpeg
|
||||||
|
|
||||||
|
ffmpeg = CameraMjpeg(self._ffmpeg_bin)
|
||||||
|
ffmpeg.open_camera(self._input, extra_cmd=self._extra_arguments)
|
||||||
|
return ffmpeg
|
||||||
|
|
||||||
|
def camera_image(self):
|
||||||
|
"""Return a still image response from the camera."""
|
||||||
|
with closing(self._ffmpeg_stream()) as stream:
|
||||||
|
return extract_image_from_mjpeg(stream)
|
||||||
|
|
||||||
|
def mjpeg_stream(self, response):
|
||||||
|
"""Generate an HTTP MJPEG stream from the camera."""
|
||||||
|
stream = self._ffmpeg_stream()
|
||||||
|
return response(
|
||||||
|
stream,
|
||||||
|
mimetype='multipart/x-mixed-replace;boundary=ffserver',
|
||||||
|
direct_passthrough=True
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of this camera."""
|
||||||
|
return self._name
|
@ -28,6 +28,18 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
|||||||
add_devices_callback([MjpegCamera(config)])
|
add_devices_callback([MjpegCamera(config)])
|
||||||
|
|
||||||
|
|
||||||
|
def extract_image_from_mjpeg(stream):
|
||||||
|
"""Take in a mjpeg stream object, return the jpg from it."""
|
||||||
|
data = b''
|
||||||
|
for chunk in stream:
|
||||||
|
data += chunk
|
||||||
|
jpg_start = data.find(b'\xff\xd8')
|
||||||
|
jpg_end = data.find(b'\xff\xd9')
|
||||||
|
if jpg_start != -1 and jpg_end != -1:
|
||||||
|
jpg = data[jpg_start:jpg_end + 2]
|
||||||
|
return jpg
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-instance-attributes
|
# pylint: disable=too-many-instance-attributes
|
||||||
class MjpegCamera(Camera):
|
class MjpegCamera(Camera):
|
||||||
"""An implementation of an IP camera that is reachable over a URL."""
|
"""An implementation of an IP camera that is reachable over a URL."""
|
||||||
@ -52,19 +64,8 @@ class MjpegCamera(Camera):
|
|||||||
|
|
||||||
def camera_image(self):
|
def camera_image(self):
|
||||||
"""Return a still image response from the camera."""
|
"""Return a still image response from the camera."""
|
||||||
def process_response(response):
|
|
||||||
"""Take in a response object, return the jpg from it."""
|
|
||||||
data = b''
|
|
||||||
for chunk in response.iter_content(1024):
|
|
||||||
data += chunk
|
|
||||||
jpg_start = data.find(b'\xff\xd8')
|
|
||||||
jpg_end = data.find(b'\xff\xd9')
|
|
||||||
if jpg_start != -1 and jpg_end != -1:
|
|
||||||
jpg = data[jpg_start:jpg_end + 2]
|
|
||||||
return jpg
|
|
||||||
|
|
||||||
with closing(self.camera_stream()) as response:
|
with closing(self.camera_stream()) as response:
|
||||||
return process_response(response)
|
return extract_image_from_mjpeg(response.iter_content(1024))
|
||||||
|
|
||||||
def mjpeg_stream(self, response):
|
def mjpeg_stream(self, response):
|
||||||
"""Generate an HTTP MJPEG stream from the camera."""
|
"""Generate an HTTP MJPEG stream from the camera."""
|
||||||
|
@ -88,6 +88,9 @@ gntp==1.0.3
|
|||||||
# homeassistant.components.sensor.google_travel_time
|
# homeassistant.components.sensor.google_travel_time
|
||||||
googlemaps==2.4.4
|
googlemaps==2.4.4
|
||||||
|
|
||||||
|
# homeassistant.components.camera.ffmpeg
|
||||||
|
ha-ffmpeg==0.4
|
||||||
|
|
||||||
# homeassistant.components.mqtt.server
|
# homeassistant.components.mqtt.server
|
||||||
hbmqtt==0.7.1
|
hbmqtt==0.7.1
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user