From d3b86abb2d6fd0df63998645b3dc74afb68b7fec Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Wed, 17 May 2017 04:28:39 -0400 Subject: [PATCH 1/6] Implemented ffmpeg option on Amcrest camera and upgraded to version 1.2.0 --- homeassistant/components/camera/amcrest.py | 35 +++++++++++++++------- homeassistant/components/sensor/amcrest.py | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py index 72d3120c77a086..d352b396f006d1 100644 --- a/homeassistant/components/camera/amcrest.py +++ b/homeassistant/components/camera/amcrest.py @@ -16,9 +16,9 @@ CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT) from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import ( - async_get_clientsession, async_aiohttp_proxy_web) + async_get_clientsession, async_aiohttp_proxy_web, async_aiohttp_proxy_stream) -REQUIREMENTS = ['amcrest==1.1.9'] +REQUIREMENTS = ['amcrest==1.2.0'] _LOGGER = logging.getLogger(__name__) @@ -40,7 +40,8 @@ STREAM_SOURCE_LIST = { 'mjpeg': 0, - 'snapshot': 1 + 'snapshot': 1, + 'rtsp': 2, } CONTENT_TYPE_HEADER = 'Content-Type' @@ -117,15 +118,29 @@ def handle_async_mjpeg_stream(self, request): yield from super().handle_async_mjpeg_stream(request) return - # Otherwise, stream an MJPEG image stream directly from the camera - websession = async_get_clientsession(self.hass) - streaming_url = '{0}mjpg/video.cgi?channel=0&subtype={1}'.format( - self._base_url, self._resolution) + elif 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) - stream_coro = websession.get( - streaming_url, auth=self._token, timeout=TIMEOUT) + yield from async_aiohttp_proxy_web(self.hass, request, stream_coro) + + else: + # streaming via fmpeg + from haffmpeg import CameraMjpeg + + streaming_url = self._camera.rtsp_url(typeno=self._resolution) + stream = CameraMjpeg('ffmpeg', loop=self.hass.loop) + yield from stream.open_camera( + streaming_url, extra_cmd='') + + yield from async_aiohttp_proxy_stream( + self.hass, request, stream, + 'multipart/x-mixed-replace;boundary=ffserver') + yield from stream.close() - yield from async_aiohttp_proxy_web(self.hass, request, stream_coro) @property def name(self): diff --git a/homeassistant/components/sensor/amcrest.py b/homeassistant/components/sensor/amcrest.py index 40556fbe5ad251..23f7fc4dfbeaef 100644 --- a/homeassistant/components/sensor/amcrest.py +++ b/homeassistant/components/sensor/amcrest.py @@ -19,7 +19,7 @@ from requests.exceptions import HTTPError, ConnectTimeout -REQUIREMENTS = ['amcrest==1.1.9'] +REQUIREMENTS = ['amcrest==1.2.0'] _LOGGER = logging.getLogger(__name__) From d5df7afad6997488230332202498eeca4032320c Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Wed, 17 May 2017 22:41:45 -0400 Subject: [PATCH 2/6] Added ffmpeg arguments and binary options to Amcrest camera --- homeassistant/components/camera/amcrest.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py index d352b396f006d1..36312d83421452 100644 --- a/homeassistant/components/camera/amcrest.py +++ b/homeassistant/components/camera/amcrest.py @@ -24,11 +24,14 @@ CONF_RESOLUTION = 'resolution' CONF_STREAM_SOURCE = 'stream_source' +CONF_FFMPEG_ARGUMENTS = 'ffmpeg_arguments' +CONF_FFMPEG_BINARY = 'ffmpeg_binary' DEFAULT_NAME = 'Amcrest Camera' DEFAULT_PORT = 80 DEFAULT_RESOLUTION = 'high' DEFAULT_STREAM_SOURCE = 'mjpeg' +DEFAULT_FFMPEG_BINARY = '/usr/bin/ffmpeg' NOTIFICATION_ID = 'amcrest_notification' NOTIFICATION_TITLE = 'Amcrest Camera Setup' @@ -57,6 +60,10 @@ vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, vol.Optional(CONF_STREAM_SOURCE, default=DEFAULT_STREAM_SOURCE): vol.All(vol.In(STREAM_SOURCE_LIST)), + vol.Optional(CONF_FFMPEG_ARGUMENTS, default=''): + cv.string, + vol.Optional(CONF_FFMPEG_BINARY, default=DEFAULT_FFMPEG_BINARY): + cv.string, }) @@ -95,6 +102,8 @@ def __init__(self, hass, device_info, camera): self._base_url = self._camera.get_base_url() self._hass = hass self._name = device_info.get(CONF_NAME) + self._ffmpeg_arguments = device_info.get(CONF_FFMPEG_ARGUMENTS) + self._ffmpeg_binary = device_info.get(CONF_FFMPEG_BINARY) self._resolution = RESOLUTION_LIST[device_info.get(CONF_RESOLUTION)] self._stream_source = STREAM_SOURCE_LIST[ device_info.get(CONF_STREAM_SOURCE) @@ -132,9 +141,9 @@ def handle_async_mjpeg_stream(self, request): from haffmpeg import CameraMjpeg streaming_url = self._camera.rtsp_url(typeno=self._resolution) - stream = CameraMjpeg('ffmpeg', loop=self.hass.loop) + stream = CameraMjpeg(self._ffmpeg_binary, loop=self.hass.loop) yield from stream.open_camera( - streaming_url, extra_cmd='') + streaming_url, extra_cmd=self._ffmpeg_arguments) yield from async_aiohttp_proxy_stream( self.hass, request, stream, From 764a6a39870b1ea05363ccbaaa713159a21cdecb Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Wed, 17 May 2017 23:29:00 -0400 Subject: [PATCH 3/6] Added ffmpeg as dependencies --- homeassistant/components/camera/amcrest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py index 36312d83421452..e3ab854bb0b5f2 100644 --- a/homeassistant/components/camera/amcrest.py +++ b/homeassistant/components/camera/amcrest.py @@ -19,6 +19,7 @@ async_get_clientsession, async_aiohttp_proxy_web, async_aiohttp_proxy_stream) REQUIREMENTS = ['amcrest==1.2.0'] +DEPENDENCIES = ['ffmpeg'] _LOGGER = logging.getLogger(__name__) From 87e6ca73ef4830b9ea19264c30b50efecfa46837 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Wed, 17 May 2017 23:30:40 -0400 Subject: [PATCH 4/6] Makes lint happy and fixed requirements_all.txt --- homeassistant/components/camera/amcrest.py | 6 +++--- requirements_all.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py index e3ab854bb0b5f2..4ade2611bd34fe 100644 --- a/homeassistant/components/camera/amcrest.py +++ b/homeassistant/components/camera/amcrest.py @@ -16,7 +16,8 @@ CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT) from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import ( - async_get_clientsession, async_aiohttp_proxy_web, async_aiohttp_proxy_stream) + async_get_clientsession, async_aiohttp_proxy_web, + async_aiohttp_proxy_stream) REQUIREMENTS = ['amcrest==1.2.0'] DEPENDENCIES = ['ffmpeg'] @@ -142,7 +143,7 @@ def handle_async_mjpeg_stream(self, request): from haffmpeg import CameraMjpeg streaming_url = self._camera.rtsp_url(typeno=self._resolution) - stream = CameraMjpeg(self._ffmpeg_binary, loop=self.hass.loop) + stream = CameraMjpeg(self._ffmpeg_binary, loop=self.hass.loop) yield from stream.open_camera( streaming_url, extra_cmd=self._ffmpeg_arguments) @@ -151,7 +152,6 @@ def handle_async_mjpeg_stream(self, request): 'multipart/x-mixed-replace;boundary=ffserver') yield from stream.close() - @property def name(self): """Return the name of this camera.""" diff --git a/requirements_all.txt b/requirements_all.txt index a859a526305b8b..c8f8c5aafd9605 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -56,7 +56,7 @@ alarmdecoder==0.12.1.0 # homeassistant.components.camera.amcrest # homeassistant.components.sensor.amcrest -amcrest==1.1.9 +amcrest==1.2.0 # homeassistant.components.media_player.anthemav anthemav==1.1.8 From 4b46587703267a75c6921a799cf73841aacbd869 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Thu, 18 May 2017 01:44:05 -0400 Subject: [PATCH 5/6] Inherent the ffmpeg.binary configuration from ffmpeg component --- homeassistant/components/camera/amcrest.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py index 4ade2611bd34fe..56df703b24a740 100644 --- a/homeassistant/components/camera/amcrest.py +++ b/homeassistant/components/camera/amcrest.py @@ -12,6 +12,7 @@ import homeassistant.loader as loader from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA) +from homeassistant.components.ffmpeg import DATA_FFMPEG from homeassistant.const import ( CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT) from homeassistant.helpers import config_validation as cv @@ -27,13 +28,11 @@ CONF_RESOLUTION = 'resolution' CONF_STREAM_SOURCE = 'stream_source' CONF_FFMPEG_ARGUMENTS = 'ffmpeg_arguments' -CONF_FFMPEG_BINARY = 'ffmpeg_binary' DEFAULT_NAME = 'Amcrest Camera' DEFAULT_PORT = 80 DEFAULT_RESOLUTION = 'high' DEFAULT_STREAM_SOURCE = 'mjpeg' -DEFAULT_FFMPEG_BINARY = '/usr/bin/ffmpeg' NOTIFICATION_ID = 'amcrest_notification' NOTIFICATION_TITLE = 'Amcrest Camera Setup' @@ -64,8 +63,6 @@ vol.All(vol.In(STREAM_SOURCE_LIST)), vol.Optional(CONF_FFMPEG_ARGUMENTS, default=''): cv.string, - vol.Optional(CONF_FFMPEG_BINARY, default=DEFAULT_FFMPEG_BINARY): - cv.string, }) @@ -102,10 +99,9 @@ def __init__(self, hass, device_info, camera): super(AmcrestCam, self).__init__() self._camera = camera self._base_url = self._camera.get_base_url() - self._hass = hass self._name = device_info.get(CONF_NAME) + self._ffmpeg = hass.data[DATA_FFMPEG] self._ffmpeg_arguments = device_info.get(CONF_FFMPEG_ARGUMENTS) - self._ffmpeg_binary = device_info.get(CONF_FFMPEG_BINARY) self._resolution = RESOLUTION_LIST[device_info.get(CONF_RESOLUTION)] self._stream_source = STREAM_SOURCE_LIST[ device_info.get(CONF_STREAM_SOURCE) @@ -143,7 +139,7 @@ def handle_async_mjpeg_stream(self, request): from haffmpeg import CameraMjpeg streaming_url = self._camera.rtsp_url(typeno=self._resolution) - stream = CameraMjpeg(self._ffmpeg_binary, loop=self.hass.loop) + stream = CameraMjpeg(self._ffmpeg.binary, loop=self.hass.loop) yield from stream.open_camera( streaming_url, extra_cmd=self._ffmpeg_arguments) From 2e936b43922881f63ce98fa74e685101ee0a8059 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Thu, 18 May 2017 09:34:39 +0200 Subject: [PATCH 6/6] Update amcrest.py --- homeassistant/components/camera/amcrest.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/camera/amcrest.py b/homeassistant/components/camera/amcrest.py index 56df703b24a740..8f8b7e5f9f53fd 100644 --- a/homeassistant/components/camera/amcrest.py +++ b/homeassistant/components/camera/amcrest.py @@ -61,8 +61,7 @@ vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, vol.Optional(CONF_STREAM_SOURCE, default=DEFAULT_STREAM_SOURCE): vol.All(vol.In(STREAM_SOURCE_LIST)), - vol.Optional(CONF_FFMPEG_ARGUMENTS, default=''): - cv.string, + vol.Optional(CONF_FFMPEG_ARGUMENTS): cv.string, })