Fix camera mjpeg stream handling (#18076)

* Fix handle_async_mjpeg_stream

* Lint
This commit is contained in:
Jason Hu 2018-11-01 01:28:23 -07:00 committed by Pascal Vizeli
parent 32ee4f0714
commit f516550f9f
10 changed files with 52 additions and 39 deletions

View File

@ -299,7 +299,8 @@ class Camera(Entity):
a direct stream from the camera.
This method must be run in the event loop.
"""
await self.handle_async_still_stream(request, self.frame_interval)
return await self.handle_async_still_stream(
request, self.frame_interval)
@property
def state(self):

View File

@ -59,8 +59,7 @@ class AmcrestCam(Camera):
"""Return an MJPEG stream."""
# The snapshot implementation is handled by the parent class
if self._stream_source == STREAM_SOURCE_LIST['snapshot']:
await super().handle_async_mjpeg_stream(request)
return
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
@ -69,20 +68,22 @@ class AmcrestCam(Camera):
stream_coro = websession.get(
streaming_url, auth=self._token, timeout=TIMEOUT)
await async_aiohttp_proxy_web(self.hass, request, stream_coro)
return await async_aiohttp_proxy_web(
self.hass, request, stream_coro)
else:
# streaming via fmpeg
from haffmpeg import CameraMjpeg
# streaming via ffmpeg
from haffmpeg 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)
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)
await async_aiohttp_proxy_stream(
try:
return await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
finally:
await stream.close()
@property

View File

@ -101,10 +101,12 @@ class ArloCam(Camera):
await stream.open_camera(
video.video_url, extra_cmd=self._ffmpeg_arguments)
await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
await stream.close()
try:
return await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
finally:
await stream.close()
@property
def name(self):

View File

@ -98,10 +98,12 @@ class CanaryCamera(Camera):
self._live_stream_session.live_stream_url,
extra_cmd=self._ffmpeg_arguments)
await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
await stream.close()
try:
return await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
finally:
await stream.close()
@Throttle(MIN_TIME_BETWEEN_SESSION_RENEW)
def renew_live_stream_session(self):

View File

@ -134,8 +134,7 @@ class MjpegCamera(Camera):
"""Generate an HTTP MJPEG stream from the camera."""
# aiohttp don't support DigestAuth -> Fallback
if self._authentication == HTTP_DIGEST_AUTHENTICATION:
await super().handle_async_mjpeg_stream(request)
return
return await super().handle_async_mjpeg_stream(request)
# connect to stream
websession = async_get_clientsession(self.hass)

View File

@ -221,10 +221,12 @@ class ONVIFHassCamera(Camera):
await stream.open_camera(
self._input, extra_cmd=self._ffmpeg_arguments)
await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
await stream.close()
try:
return await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
finally:
await stream.close()
@property
def name(self):

View File

@ -139,10 +139,12 @@ class RingCam(Camera):
await stream.open_camera(
self._video_url, extra_cmd=self._ffmpeg_arguments)
await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
await stream.close()
try:
return await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
finally:
await stream.close()
@property
def should_poll(self):

View File

@ -92,7 +92,7 @@ class SynologyCamera(Camera):
websession = async_get_clientsession(self.hass, self._verify_ssl)
stream_coro = websession.get(streaming_url)
await async_aiohttp_proxy_web(self.hass, request, stream_coro)
return await async_aiohttp_proxy_web(self.hass, request, stream_coro)
@property
def name(self):

View File

@ -158,7 +158,9 @@ class XiaomiCamera(Camera):
await stream.open_camera(
self._last_url, extra_cmd=self._extra_arguments)
await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
await stream.close()
try:
return await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
finally:
await stream.close()

View File

@ -144,7 +144,9 @@ class YiCamera(Camera):
await stream.open_camera(
self._last_url, extra_cmd=self._extra_arguments)
await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
await stream.close()
try:
return await async_aiohttp_proxy_stream(
self.hass, request, stream,
'multipart/x-mixed-replace;boundary=ffserver')
finally:
await stream.close()