Issue
I need help showing a variable from Python in Html. Is it possible to pass the current time from Python with every frame to the Html with blocking the video stream?
I need it to verify that the video stream is alive on a Raspberry Pi running Windows IoT Core.
I have tried with the time coming from Html, but that doesn’t work because the time continues even when the stream has stopped.
Tia, Henrik
My Python script
from threading import Condition
from http import server
import datetime
timenow = datetime.datetime.now()
print(timenow)
PAGE="""\
<html>
<head>
<title>picamera MJPEG streaming demo </title>
</head>
<body onload="startTime()" bgcolor="#000000">
<img src="stream.mjpg" width="480" height="270"/>
<p>{timenow}</p>
</body>
</html>
"""
class StreamingOutput(object):
def __init__(self):
self.frame = None
self.buffer = io.BytesIO()
self.condition = Condition()
def write(self, buf):
if buf.startswith(b'\xff\xd8'):
# New frame, copy the existing buffer's content and notify all
# clients it's available
self.buffer.truncate()
with self.condition:
self.frame = self.buffer.getvalue()
self.condition.notify_all()
self.buffer.seek(0)
return self.buffer.write(buf)
class StreamingHandler(server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
self.send_response(301)
self.send_header('Location', '/index.html')
self.end_headers()
elif self.path == '/index.html':
content = PAGE.encode('utf-8')
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.send_header('Content-Length', len(content))
self.end_headers()
self.wfile.write(content)
elif self.path == '/stream.mjpg':
self.send_response(200)
self.send_header('Age', 0)
self.send_header('Cache-Control', 'no-cache, private')
self.send_header('Pragma', 'no-cache')
self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME')
self.end_headers()
# print(now)
try:
while True:
with output.condition:
output.condition.wait()
frame = output.frame
self.wfile.write(b'--FRAME\r\n')
self.send_header('Content-Type', 'image/jpeg')
self.send_header('Content-Length', len(frame))
self.end_headers()
self.wfile.write(frame)
self.wfile.write(b'\r\n')
except Exception as e:
logging.warning(
'Removed streaming client %s: %s',
self.client_address, str(e))
else:
self.send_error(404)
self.end_headers()
class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer):
allow_reuse_address = True
daemon_threads = True
with picamera.PiCamera(resolution='480x270', framerate=12) as camera:
output = StreamingOutput()
camera.rotation=180
camera.start_recording(output, format='mjpeg')
try:
address = ('', 8000)
server = StreamingServer(address, StreamingHandler)
server.serve_forever()
finally:
camera.stop_recording()
Solution
You were basically doing it only once, at the beginning of the script, and when you execute the script to run the server you basically evaluate datetime.now()
only once, instead what you need to do is evaluate if for every GET
request.
In order to add it to the stream response itself, since it is a multipart
you can just add another response section with the
Content-Type: application/json
Content-Length: ... what ever the length of the time string is
and then just add a json
dump string of the timenow like this: json.dumps( { "timenow": str(datetime.datetime.now()) } )
and then you have to parse the JSON response of the additional multipart section on the frontend.
def do_GET(self):
if self.path == '/':
...
elif self.path == '/index.html':
timenow = datetime.datetime.now()
content = PAGE.format(timenow=timenow).encode('utf-8')
... the rest of the code
elif self.path == '/stream.mjpg':
...
try:
while True:
with output.condition:
output.condition.wait()
frame = output.frame
# add the frame
self.wfile.write(b'--FRAME\r\n')
self.send_header('Content-Type', 'image/jpeg')
self.send_header('Content-Length', len(frame))
self.end_headers()
self.wfile.write(frame)
self.wfile.write(b'\r\n')
# add the time information
timenow = str(datetime.datetime.now())
self.wfile.write(b'--TIME\r\n')
self.send_header('Content-Type', 'application/json')
self.send_header('Content-Length' len(timenow)),
self.end_headers()
self.wfile.write(json.dumps({"timenow": timenow}).encode('utf-8))
self.wfile.write(b'\r\n')
except Exception as e:
logging.warning(
'Removed streaming client %s: %s',
self.client_address, str(e))
Answered By - andreihondrari