Added support to Amcrest camera to feed using RTSP via ffmpeg (#7646)
* Implemented ffmpeg option on Amcrest camera and upgraded to version 1.2.0 * Added ffmpeg arguments and binary options to Amcrest camera * Added ffmpeg as dependencies * Makes lint happy and fixed requirements_all.txt * Inherent the ffmpeg.binary configuration from ffmpeg component * Update amcrest.py
This commit is contained in:
parent
0eb6540fe7
commit
0fd415d7fb
3 changed files with 33 additions and 13 deletions
|
@ -12,18 +12,22 @@ import voluptuous as vol
|
||||||
|
|
||||||
import homeassistant.loader as loader
|
import homeassistant.loader as loader
|
||||||
from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA)
|
from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA)
|
||||||
|
from homeassistant.components.ffmpeg import DATA_FFMPEG
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT)
|
CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT)
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
from homeassistant.helpers.aiohttp_client import (
|
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']
|
||||||
|
DEPENDENCIES = ['ffmpeg']
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
CONF_RESOLUTION = 'resolution'
|
CONF_RESOLUTION = 'resolution'
|
||||||
CONF_STREAM_SOURCE = 'stream_source'
|
CONF_STREAM_SOURCE = 'stream_source'
|
||||||
|
CONF_FFMPEG_ARGUMENTS = 'ffmpeg_arguments'
|
||||||
|
|
||||||
DEFAULT_NAME = 'Amcrest Camera'
|
DEFAULT_NAME = 'Amcrest Camera'
|
||||||
DEFAULT_PORT = 80
|
DEFAULT_PORT = 80
|
||||||
|
@ -40,7 +44,8 @@ RESOLUTION_LIST = {
|
||||||
|
|
||||||
STREAM_SOURCE_LIST = {
|
STREAM_SOURCE_LIST = {
|
||||||
'mjpeg': 0,
|
'mjpeg': 0,
|
||||||
'snapshot': 1
|
'snapshot': 1,
|
||||||
|
'rtsp': 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
CONTENT_TYPE_HEADER = 'Content-Type'
|
CONTENT_TYPE_HEADER = 'Content-Type'
|
||||||
|
@ -56,6 +61,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||||
vol.Optional(CONF_STREAM_SOURCE, default=DEFAULT_STREAM_SOURCE):
|
vol.Optional(CONF_STREAM_SOURCE, default=DEFAULT_STREAM_SOURCE):
|
||||||
vol.All(vol.In(STREAM_SOURCE_LIST)),
|
vol.All(vol.In(STREAM_SOURCE_LIST)),
|
||||||
|
vol.Optional(CONF_FFMPEG_ARGUMENTS): cv.string,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,8 +98,9 @@ class AmcrestCam(Camera):
|
||||||
super(AmcrestCam, self).__init__()
|
super(AmcrestCam, self).__init__()
|
||||||
self._camera = camera
|
self._camera = camera
|
||||||
self._base_url = self._camera.get_base_url()
|
self._base_url = self._camera.get_base_url()
|
||||||
self._hass = hass
|
|
||||||
self._name = device_info.get(CONF_NAME)
|
self._name = device_info.get(CONF_NAME)
|
||||||
|
self._ffmpeg = hass.data[DATA_FFMPEG]
|
||||||
|
self._ffmpeg_arguments = device_info.get(CONF_FFMPEG_ARGUMENTS)
|
||||||
self._resolution = RESOLUTION_LIST[device_info.get(CONF_RESOLUTION)]
|
self._resolution = RESOLUTION_LIST[device_info.get(CONF_RESOLUTION)]
|
||||||
self._stream_source = STREAM_SOURCE_LIST[
|
self._stream_source = STREAM_SOURCE_LIST[
|
||||||
device_info.get(CONF_STREAM_SOURCE)
|
device_info.get(CONF_STREAM_SOURCE)
|
||||||
|
@ -117,15 +124,28 @@ class AmcrestCam(Camera):
|
||||||
yield from super().handle_async_mjpeg_stream(request)
|
yield from super().handle_async_mjpeg_stream(request)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Otherwise, stream an MJPEG image stream directly from the camera
|
elif self._stream_source == STREAM_SOURCE_LIST['mjpeg']:
|
||||||
websession = async_get_clientsession(self.hass)
|
# stream an MJPEG image stream directly from the camera
|
||||||
streaming_url = '{0}mjpg/video.cgi?channel=0&subtype={1}'.format(
|
websession = async_get_clientsession(self.hass)
|
||||||
self._base_url, self._resolution)
|
streaming_url = self._camera.mjpeg_url(typeno=self._resolution)
|
||||||
|
stream_coro = websession.get(
|
||||||
|
streaming_url, auth=self._token, timeout=TIMEOUT)
|
||||||
|
|
||||||
stream_coro = websession.get(
|
yield from async_aiohttp_proxy_web(self.hass, request, stream_coro)
|
||||||
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(self._ffmpeg.binary, loop=self.hass.loop)
|
||||||
|
yield from stream.open_camera(
|
||||||
|
streaming_url, extra_cmd=self._ffmpeg_arguments)
|
||||||
|
|
||||||
|
yield from async_aiohttp_proxy_stream(
|
||||||
|
self.hass, request, stream,
|
||||||
|
'multipart/x-mixed-replace;boundary=ffserver')
|
||||||
|
yield from stream.close()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
|
|
@ -19,7 +19,7 @@ import homeassistant.loader as loader
|
||||||
|
|
||||||
from requests.exceptions import HTTPError, ConnectTimeout
|
from requests.exceptions import HTTPError, ConnectTimeout
|
||||||
|
|
||||||
REQUIREMENTS = ['amcrest==1.1.9']
|
REQUIREMENTS = ['amcrest==1.2.0']
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ alarmdecoder==0.12.1.0
|
||||||
|
|
||||||
# homeassistant.components.camera.amcrest
|
# homeassistant.components.camera.amcrest
|
||||||
# homeassistant.components.sensor.amcrest
|
# homeassistant.components.sensor.amcrest
|
||||||
amcrest==1.1.9
|
amcrest==1.2.0
|
||||||
|
|
||||||
# homeassistant.components.media_player.anthemav
|
# homeassistant.components.media_player.anthemav
|
||||||
anthemav==1.1.8
|
anthemav==1.1.8
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue