You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

137 lines
4.3 KiB

from datetime import datetime
from dvrip import DVRIPCam
import json
import struct
NVR_DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
class File:
def __init__(self, data, channel = 0) -> None:
self.begin = datetime.strptime(data.get("BeginTime"), NVR_DATETIME_FORMAT)
self.end = datetime.strptime(data.get("EndTime"), NVR_DATETIME_FORMAT)
self.diskNo = data.get("DiskNo")
self.SerialNo = data.get("SerialNo")
self.size = int(data.get("FileLength"), 0)
self.filename = data.get("FileName")
self.channel = channel
def __str__(self) -> str:
return self.filename
def __repr__(self) -> str:
return self.__str__()
def download_stream(self, client:DVRIPCam, stream = 0, version = 0):
#init request
client.send(
1424,
{
"Name": "OPPlayBack",
"OPPlayBack": {
"Action": "Claim",
"Parameter": {
"PlayMode": "ByName",
"FileName": self.filename,
"StreamType": stream,
"Value": 0,
"TransMode": "TCP",
},
"StartTime": self.begin.strftime(NVR_DATETIME_FORMAT),
"EndTime": self.end.strftime(NVR_DATETIME_FORMAT),
},
},
)
#download request
msg = 1420
data = {
"Name": "OPPlayBack",
"OPPlayBack": {
"Action": "DownloadStart",
"Parameter": {
"PlayMode": "ByName",
"FileName": self.filename,
"StreamType": stream,
"Value": 0,
"TransMode": "TCP",
},
"StartTime": self.begin.strftime(NVR_DATETIME_FORMAT),
"EndTime": self.end.strftime(NVR_DATETIME_FORMAT),
},
}
if client.socket is None:
#todo raise error
return []
client.busy.acquire()
if hasattr(data, "__iter__"):
if version == 1:
data["SessionID"] = f"{client.session:#0{12}x}"
data = bytes(
json.dumps(data, ensure_ascii=False, separators=(",", ":")), "utf-8"
)
tail = b"\x00"
if version == 0:
tail = b"\x0a" + tail
pkt = (
struct.pack(
"BB2xII2xHI",
255,
version,
client.session,
client.packet_count,
msg,
len(data) + len(tail),
)
+ data
+ tail
)
client.socket_send(pkt)
data = client.socket_recv(20)
if data is None or len(data) < 20:
return []
(
head,
version,
client.session,
sequence_number,
msgid,
len_data,
) = struct.unpack("BB2xII2xHI", data)
return self.get_file_stream(client, len_data, stream)
def get_file_stream(self, client, first_chunk_size, stream):
yield client.receive_with_timeout(first_chunk_size)
while True:
header = client.receive_with_timeout(20)
len_data = struct.unpack("I", header[16:])[0]
if len_data == 0:
break
yield client.receive_with_timeout(len_data)
client.busy.release()
client.send(
1420,
{
"Name": "OPPlayBack",
"OPPlayBack": {
"Action": "DownloadStop",
"Parameter": {
"FileName": self.filename,
"PlayMode": "ByName",
"StreamType": stream,
"TransMode": "TCP",
"Channel": self.channel,
"Value": 0,
},
"StartTime": self.begin.strftime(NVR_DATETIME_FORMAT),
"EndTime": self.end.strftime(NVR_DATETIME_FORMAT),
},
},
)
yield b""