Coder Social home page Coder Social logo

alexshpilkin / dvrip Goto Github PK

View Code? Open in Web Editor NEW
63.0 8.0 29.0 370 KB

Python DVRIP (Xiongmai, XMEye, Sofia protocol) library and tools

License: Creative Commons Zero v1.0 Universal

Python 100.00%
dvrip xmeye xiongmai xiongmaitech sofia netsurveillance dvr cctv

dvrip's Introduction

DVRIP (Xiongmai, XMEye, Sofia protocol) library and tools

dvrip's People

Contributors

alexshpilkin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dvrip's Issues

Camera Settings

Hi,
Can you add capability to change settings of camera?

I have the communication between XMeye and Camera recorded, and this is how it goes:

..... ...........I...{ "Camera.Param.[0]" : { "AeSensitivity" : 7, "ApertureMode" : "0x00000001", "BLCMode" : "0x00000001", "DayNightColor" : "0x00000000", "Day_nfLevel" : 3, "DncThr" : 30, "ElecLevel" : 50, "EsShutter" : "0x00000006", "ExposureParam" : { "LeastTime" : "0x00000064", "Level" : 0, "MostTime" : "0x00010000" }, "GainParam" : { "AutoGain" : 0, "Gain" : 50 }, "IRCUTMode" : 1, "IrcutSwap" : 0, "Night_nfLevel" : 3, "PictureFlip" : "0x00000001", "PictureMirror" : "0x00000001", "RejectFlicker" : "0x00000000", "WhiteBalance" : "0x00000000" }, "Name" : "Camera.Param.[0]", "SessionID" : "0x9" }

Binary:
ff000000060000001800000000001004490200007b202243616d6572612e506172616d2e5b305d22203a207b2022416553656e736974697669747922203a20372c202241706572747572654d6f646522203a202230783030303030303031222c2022424c434d6f646522203a202230783030303030303031222c20224461794e69676874436f6c6f7222203a202230783030303030303030222c20224461795f6e664c6576656c22203a20332c2022446e6354687222203a2033302c2022456c65634c6576656c22203a2035302c202245735368757474657222203a202230783030303030303036222c20224578706f73757265506172616d22203a207b20224c6561737454696d6522203a202230783030303030303634222c20224c6576656c22203a20302c20224d6f737454696d6522203a20223078303030313030303022207d2c20224761696e506172616d22203a207b20224175746f4761696e22203a20302c20224761696e22203a203530207d2c202249524355544d6f646522203a20312c202249726375745377617022203a20302c20224e696768745f6e664c6576656c22203a20332c202250696374757265466c697022203a202230783030303030303031222c2022506963747572654d6972726f7222203a202230783030303030303031222c202252656a656374466c69636b657222203a202230783030303030303030222c2022576869746542616c616e636522203a20223078303030303030303022207d2c20224e616d6522203a202243616d6572612e506172616d2e5b305d222c202253657373696f6e494422203a202230783622207d0a

Receive after

.... ...........:...{ "Name" : "", "Ret" : 100, "SessionID" : "0x00000009" }

How do you install and use this?

Looks good from peeking into the code - but how to use? I don't seem to even be able to install it (on Ubuntu 20 - I don't have much idea with python personally).

Appreciate there have been a couple of issues raised about the readme but in the absence of a readme maybe someone else can just leave a comment saying basically how to install and run it?

Make it async?

Hi Alex,
thank you for great job. Awsame!

I'm trying to integrate this library with Home-Assistant. My concern is to make it work async. Home Assistant is using asyncio and I'm trying to send stream from camera using monitor to pipe then read it with ffmped and then process.
Do you have time to make it async?

Requiring using the launcher is silly

Failing with #6, we're proceeding with python3.7 -m venv .... Looking at setup.py there're bunch of dvr-* entrypoint. But running them have no effect:

(.venv) dvrip$ dvr-info
Usage:  info
(.venv) dvrip$ dvr-info 192.168.1.10
Usage:  info
(.venv) dvrip$ dvr-info -h 192.168.1.10
Usage:  info

That's apparently because "calling conventions" for subcommands have changed, and nowadays

	if host() is None:
		usage()

is always true.

README template or just USAGE example

hello! i've wrote example code of core features from this project, so you can just use it as a wiki.
the snapshoting function now relies on PyAV library which costs additional 45MB when code compiled,
but i'm in progress of writing my own h264 decoder in python3, which i would be glad to share either.

import socket
import traceback

from io import BytesIO
from PIL import Image
from av.packet import Packet
from av.codec.context import CodecContext

from dvrip.monitor import Stream
from dvrip.io import DVRIPClient


Status = {
		None: 0,
		'Wrong password': -1,
		'Banned': 2
	}

class XMEye:
	def __init__(self, ip=None, port=None):
		self.ip = ip
		self.port = port
		self.login = None
		self.password = None

	def auth(self, login, password):
		global Status

		self.Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.Socket.settimeout(4)
		self.conn = DVRIPClient(self.Socket)
		log_in = self.conn.connect((self.ip, self.port), login, password)
		return Status[log_in]

	def get_snapshot(self, ch):
		self.Socket2 = socket.create_connection((self.ip, self.port), 11)
		h264 = self.conn.monitor(self.Socket2, channel=ch, stream=Stream.HD)

		data = b''
		while True:
			if chunk := h264.read(1024):
				data += chunk
			if len(chunk) < 1024:
				break

		self.codec_264 = CodecContext.create("h264", "r")
		frame = self.codec_264.decode(Packet(data)):
#		frame[0].to_image().save(f'frame_{frame.index}.jpg')
		jpeg = BytesIO()
		frame[0].to_image().save(jpeg, format='JPEG')
		if ch == self.channels:
			self.conn.logout()
			self.Socket2.close()
		return jpeg.getvalue()

	def sys_info(self):
		info = self.conn.systeminfo()
		self.channels_count = int(info.videoin)
		self.model = f'{info.chassis}_{info.board}'
		try:
			ptz = self.conn.button(channel=0, button=PTZButton.MENU)
		except DVRIPRequestError:
			ptz = None
		if int(info.audioin) > 0 and ptz is None:
			self.model = f'{self.model}-Sound'
		elif ptz is not None:
			self.model = f'{self.model}-PTZ'
		return

#	def debug(self):
#		self.conn.keepalive()

typing.py issubclass()

Hi alex

I have installed your dvrip via pip but i am struggling to run your code pass this error

File "C:\Python36\lib\site-packages\dvrip\typing.py", line 80, in json_to
return type.json_to # type: ignore
AttributeError: 'tuple' object has no attribute 'json_to'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "dvrip_test.py", line 8, in
from dvrip.io import DVRIPClient
File "C:\Python36\lib\site-packages\dvrip\io.py", line 8, in
from .info import GetInfo, Info
File "C:\Python36\lib\site-packages\dvrip\info.py", line 72, in
class DiskInfo(Object):
File "C:\Python36\lib\site-packages\dvrip\typing.py", line 360, in new
member.set_name(self, mname)
File "C:\Python36\lib\site-packages\dvrip\typing.py", line 301, in set_name
self.pipe = (jsontype(get_args(ann)[0]),)
File "C:\Python36\lib\site-packages\dvrip\typing.py", line 138, in jsontype
return (json_to(type), for_json)
File "C:\Python36\lib\site-packages\dvrip\typing.py", line 87, in json_to
if issubclass(type, bool): # needs to come before 'int'
TypeError: issubclass() arg 1 must be a class

when you print whats happening it getting stuck on

(typing.List, <class 'dvrip.info.PartitionInfo'>)

i am using python 3.6.7 on windows

many thanks
jon

Entry points should work with python -m

I'm not sure if I find empathy here, but my system is not made of rubber. If I'll install all the things I try (even in virtualenv), it will be a mess. That's pretty much why I use Python - that I can clone, review code, run, and hack on it, all without extra unneeded motions.

Let's try it here:

$ python3.7 -m dvrip.cmd
/usr/bin/python3.7: No module named dvrip.cmd.__main__; 'dvrip.cmd' is a package and cannot be directly executed

Oops. Following an observation in #5, looks like some contrast with depending on features which aren't available in default Python installed in many distro nowadays (3.5-3.6), and not having old good (by now) __main__.py.

Following patch allows to proceed further:

diff --git a/dvrip/cmd/__main__.py b/dvrip/cmd/__main__.py
new file mode 100644
index 0000000..e7d3e76
--- /dev/null
+++ b/dvrip/cmd/__main__.py
@@ -0,0 +1,4 @@
+from . import main
+
+
+main()

Downloading recordings

Hi,
thank you for the project.

I am trying to download all video files which I list with conn.files()

This is the function I am using:

def download(file):
    socket = Socket(AF_INET, SOCK_STREAM)

    conn = DVRIPClient(socket)
    conn.connect((argv[1], DVRIP_PORT), argv[2], argv[3])

    sock = Socket(AF_INET, SOCK_STREAM)
    sock.connect((argv[1], DVRIP_PORT))


    namepart = file.name.split('/')
    print(namepart)

    newname = "{}-{}".format(namepart[2], namepart[4])

    if os.path.exists(newname):
        have = os.path.getsize(newname)

        if have == file.length*1024:
            print("file complete")
            return

    sz = 0
    lastping = 0

    rdr = conn.download(sock, file.name)

    with open(newname, 'wb') as out:
        while True:
            chunk = rdr.read(16)
            sz += len(chunk)
            #print(sz)
            if not chunk: break
            out.write(chunk)
            out.flush()

            if time.time() > lastping + 10:
                lastping = time.time()
                print(conn.storageinfo())
    sock.close()

this only started working after I patched playback like this:

diff --git a/dvrip/playback.py b/dvrip/playback.py
index 6668ce5..4ad296f 100644
--- a/dvrip/playback.py
+++ b/dvrip/playback.py
@@ -26,6 +26,7 @@ class PlaybackParams(Object):
        # TODO there are more
        name:      member[str] = member('FileName')
        transport: fixedmember = fixedmember('TransMode', 'TCP')  # TODO
+       playmode:  fixedmember = fixedmember('PlayMode', 'ByName')
 
 class Playback(Object):
        action: member[PlaybackAction] = member('Action')

I took the parameter from a capture I made during download using the original activeX plugin:

 "Name" : "OPPlayBack", "OPPlayBack" : { "Action" : "Claim", "EndTime" : "2023-10-26 08:28:41", "Parameter" : { "FileName" : "/idea0/2023-10-26/001/08.25.00-08.28.41[R][@355c][0].h264", "IntelligentPlayBackEvent" : "", "IntelligentPlayBackSpeed" : -1, "PlayMode" : "ByName", "StreamType" : 0, "TransMode" : "TCP", "Value" : 0 }, "StartTime" : "2023-10-26 08:25:00" }, "SessionID" : "0x763" }

Before this, the downloaded file didn't match the FileSize parameter (maybe related to #9 ?)

There is one weird thing though, I need to keep "pinging" the api using some command (see conn.storageinfo() in my code) to prevent the download from freezing. This helps but it still freezes sometimes.

Do you have some idea how to make this flawless?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.