mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 18:27:09 +00:00
Fix camera
This commit is contained in:
parent
aa34fe15b2
commit
4d7555957c
@ -29,9 +29,6 @@ STATE_IDLE = 'idle'
|
|||||||
|
|
||||||
ENTITY_IMAGE_URL = '/api/camera_proxy/{0}'
|
ENTITY_IMAGE_URL = '/api/camera_proxy/{0}'
|
||||||
|
|
||||||
MULTIPART_BOUNDARY = '--jpgboundary'
|
|
||||||
MJPEG_START_HEADER = 'Content-type: {0}\r\n\r\n'
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
def setup(hass, config):
|
def setup(hass, config):
|
||||||
@ -87,10 +84,8 @@ class Camera(Entity):
|
|||||||
def mjpeg_stream(self, response):
|
def mjpeg_stream(self, response):
|
||||||
"""Generate an HTTP MJPEG stream from camera images."""
|
"""Generate an HTTP MJPEG stream from camera images."""
|
||||||
import eventlet
|
import eventlet
|
||||||
response.mimetype = ('multipart/x-mixed-replace; '
|
response.content_type = ('multipart/x-mixed-replace; '
|
||||||
'boundary={}'.format(MULTIPART_BOUNDARY))
|
'boundary=--jpegboundary')
|
||||||
|
|
||||||
boundary = bytes('\r\n{}\r\n'.format(MULTIPART_BOUNDARY), 'utf-8')
|
|
||||||
|
|
||||||
def stream():
|
def stream():
|
||||||
"""Stream images as mjpeg stream."""
|
"""Stream images as mjpeg stream."""
|
||||||
@ -99,16 +94,14 @@ class Camera(Entity):
|
|||||||
while True:
|
while True:
|
||||||
img_bytes = self.camera_image()
|
img_bytes = self.camera_image()
|
||||||
|
|
||||||
if img_bytes is None:
|
if img_bytes is not None and img_bytes != last_image:
|
||||||
continue
|
yield bytes(
|
||||||
elif img_bytes == last_image:
|
'--jpegboundary\r\n'
|
||||||
eventlet.sleep(0.5)
|
'Content-Type: image/jpeg\r\n'
|
||||||
|
'Content-Length: {}\r\n\r\n'.format(
|
||||||
|
len(img_bytes)), 'utf-8') + img_bytes + b'\r\n'
|
||||||
|
|
||||||
yield bytes('Content-length: {}'.format(len(img_bytes)) +
|
last_image = img_bytes
|
||||||
'\r\nContent-type: image/jpeg\r\n\r\n',
|
|
||||||
'utf-8')
|
|
||||||
yield img_bytes
|
|
||||||
yield boundary
|
|
||||||
|
|
||||||
eventlet.sleep(0.5)
|
eventlet.sleep(0.5)
|
||||||
except GeneratorExit:
|
except GeneratorExit:
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import hmac
|
import hmac
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import mimetypes
|
||||||
import threading
|
import threading
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -333,7 +334,7 @@ class HomeAssistantView(object):
|
|||||||
"""Return a JSON message response."""
|
"""Return a JSON message response."""
|
||||||
return self.json({'message': error}, status_code)
|
return self.json({'message': error}, status_code)
|
||||||
|
|
||||||
def file(self, request, fil, content_type=None):
|
def file(self, request, fil, mimetype=None):
|
||||||
"""Return a file."""
|
"""Return a file."""
|
||||||
from werkzeug.wsgi import wrap_file
|
from werkzeug.wsgi import wrap_file
|
||||||
from werkzeug.exceptions import NotFound
|
from werkzeug.exceptions import NotFound
|
||||||
@ -344,9 +345,8 @@ class HomeAssistantView(object):
|
|||||||
except IOError:
|
except IOError:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
# TODO mimetypes, etc
|
if mimetype is None:
|
||||||
|
mimetype = mimetypes.guess_type(fil)[0]
|
||||||
|
|
||||||
resp = self.Response(wrap_file(request.environ, fil))
|
return self.Response(wrap_file(request.environ, fil),
|
||||||
if content_type is not None:
|
mimetype=mimetype, direct_passthrough=True)
|
||||||
resp.mimetype = content_type
|
|
||||||
return resp
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user