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
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""
|
|
|
|
|
|
|