After sending the device.start_livestream command, I start recieving the buffer containng the video data, but I don't always get completed buffer, which casues the codec decode command to return error.
Here is my Python implemention of the client and showing a live video from the server:
def on_message(ws, message):
data = json.loads(message)
message_type = data["type"]
if message_type == "event" and data["event"]["event"] == "livestream video data":
image_buffer = data["event"]["buffer"]["data"]
if not is_h264_complete(image_buffer):
print("Error! incomplete h264 data")
return
buffer_bytes = bytes(image_buffer)
packet = av.Packet(buffer_bytes)
codec = av.CodecContext.create('h264', 'r')
frames = codec.decode(packet)
# Display the image
for frame in frames:
image = frame.to_ndarray(format='bgr24')
cv2.imshow('Image', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
To reproduce
Run eufy-security-server with node (you may need to change the serial number)
And then run this python file:
import websocket
import json
import av
import numpy as np
import cv2
def is_h264_complete(buffer):
# Convert the buffer to bytes
buffer_bytes = bytes(buffer)
# Look for the start code in the buffer
start_code = bytes([0, 0, 0, 1])
positions = [i for i in range(len(buffer_bytes)) if buffer_bytes.startswith(start_code, i)]
# Check for the presence of SPS and PPS
has_sps = any(buffer_bytes[i+4] & 0x1F == 7 for i in positions)
has_pps = any(buffer_bytes[i+4] & 0x1F == 8 for i in positions)
return has_sps and has_pps
def on_message(ws, message):
data = json.loads(message)
message_type = data["type"]
if message_type == "event" and data["event"]["event"] == "livestream video data":
image_buffer = data["event"]["buffer"]["data"]
if not is_h264_complete(image_buffer):
print("Error! incomplete h264 data")
return
buffer_bytes = bytes(image_buffer)
packet = av.Packet(buffer_bytes)
codec = av.CodecContext.create('h264', 'r')
frames = codec.decode(packet)
# Display the image
for frame in frames:
image = frame.to_ndarray(format='bgr24')
cv2.imshow('Image', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
'''
if message_type == "event" and "name" in message_type:
if message_type["name"] == "personName":
print(f"Person Detected!")
'''
def on_error(ws, error):
print(f"Error: {error}")
def on_close(ws):
print("Connection closed")
def on_open(ws):
print("Connection opened")
# Send a message to the server
ws.send(json.dumps({"messageId" : "start_listening", "command": "start_listening"})) # replace with your command and parameters
ws.send(json.dumps({"command": "set_api_schema", "schemaVersion" : 20}))
ws.send(json.dumps({"messageId" : "start_livestream", "command": "device.start_livestream", "serialNumber": "T8410P4223334EBE"})) # replace with your command and parameters
if __name__ == "__main__":
websocket.enableTrace(False)
ws = websocket.WebSocketApp("ws://localhost:3000", # replace with your server URI
on_message=on_message,
on_error=on_error,
on_close=on_close)
ws.on_open = on_open
ws.run_forever()
Screenshots & Logfiles
Seems like I get different lengths of the buffer every time, such as:
Version
1.7.1
Node version
20.11.0
Operating System type
Windows
Operating system version
Windows 10
Describe the bug
After sending the
device.start_livestream
command, I start recieving the buffer containng the video data, but I don't always get completed buffer, which casues the codec decode command to return error.Here is my Python implemention of the client and showing a live video from the server:
To reproduce
Run
eufy-security-server
with node (you may need to change the serial number) And then run this python file:Screenshots & Logfiles
Seems like I get different lengths of the buffer every time, such as:
48774 1728 3467 11949 14267 11974 13556 17097 8486 6615 9923 8697 5014
Additional context
No response