运行前应检测摄像头是否开启onvif协议,并添加添加用户:
配置->网络->高级配置->集成协议:
开启开放型网络视频接口
添加用户
import time
import zeep
import requests
from onvif import ONVIFCamera
from requests.auth import HTTPDigestAuth
def zeep_pythonvalue(self, xmlvalue):
return xmlvalue
# ########################## Move Camera ##########################
class CameraZoom:
def __init__(self, ip="172.22.49.9", port=80, username="abcd", password="123456"):
mycam = ONVIFCamera(ip, port, username, password)
mycam.devicemgmt.GetServices(False)
media = mycam.create_media_service() # Create media service object
self.ptz = mycam.create_ptz_service() # Create self.ptz service object
# Get target profile
zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
media_profile = media.GetProfiles()[0]
self.ptz.Stop({'ProfileToken': media_profile.token})
# Get PTZ configuration options for getting continuous move range
config = self.ptz.create_type('GetConfigurationOptions')
config.ConfigurationToken = media_profile.PTZConfiguration.token
ptz_configuration_options = self.ptz.GetConfigurationOptions(config)
# RelativeMove
self.requestr = self.ptz.create_type('RelativeMove')
self.requestr.ProfileToken = media_profile.token
if self.requestr.Translation is None:
self.requestr.Translation = self.ptz.GetStatus({'ProfileToken': media_profile.token}).Position
self.requestr.Translation.PanTilt.space = ptz_configuration_options.Spaces.RelativePanTiltTranslationSpace[0].URI
self.requestr.Translation.Zoom.space = ptz_configuration_options.Spaces.RelativeZoomTranslationSpace[0].URI
if self.requestr.Speed is None:
self.requestr.Speed = self.ptz.GetStatus({'ProfileToken': media_profile.token}).Position
self.requestr.Speed.PanTilt.space = ptz_configuration_options.Spaces.RelativePanTiltTranslationSpace[0].URI
self.requestr.Speed.Zoom.space = ptz_configuration_options.Spaces.RelativeZoomTranslationSpace[0].URI
# AbsoluteMove
self.requesta = self.ptz.create_type('AbsoluteMove')
self.requesta.ProfileToken = media_profile.token
if self.requesta.Position is None:
self.requesta.Position = self.ptz.GetStatus({'ProfileToken': media_profile.token}).Position
self.requesta.Position.PanTilt.space = ptz_configuration_options.Spaces.AbsolutePanTiltPositionSpace[0].URI
self.requesta.Position.Zoom.space = ptz_configuration_options.Spaces.AbsoluteZoomPositionSpace[0].URI
if self.requesta.Speed is None:
self.requesta.Speed = self.ptz.GetStatus({'ProfileToken': media_profile.token}).Position
self.requesta.Speed.PanTilt.space = ptz_configuration_options.Spaces.AbsolutePanTiltPositionSpace[0].URI
self.requesta.Speed.Zoom.space = ptz_configuration_options.Spaces.AbsoluteZoomPositionSpace[0].URI
# CurrentStatus
params = self.ptz.create_type('GetStatus')
params.ProfileToken = media_profile.token
self.res = self.ptz.GetStatus(params)
# variables
self.default = False
self.defaultx = None
self.defaulty = None
self.defaultzoom = None
self.x_speed = 3
self.y_speed = 3
self.zoom_speed = 3
self.zoomflag = 0
def addFlag(self):
self.zoomflag += 1
def preformRelativeMove(self, xshift, yshift, zoom):
# record origin position
if self.default is False:
# set default
cx, cy, cz = self.getCurrentStatus()
self.default = True
self.defaultx = cx
self.defaulty = cy
self.defaultzoom = cz
# RelativeMove
self.requestr.Translation.PanTilt.x = xshift
self.requestr.Speed.PanTilt.x = self.x_speed
self.requestr.Translation.PanTilt.y = yshift
self.requestr.Speed.PanTilt.y = self.y_speed
self.requestr.Translation.Zoom = zoom
self.requestr.Speed.Zoom = self.zoom_speed
self.ptz.RelativeMove(self.requestr)
print('finish relative_move')
def preformAbsoluteMove(self):
# AbsoluteMove
if self.default is True:
self.requesta.Position.PanTilt.x = self.defaultx
self.requesta.Speed.PanTilt.x = self.x_speed
self.requesta.Position.PanTilt.y = self.defaulty
self.requesta.Speed.PanTilt.y = self.y_speed
self.requesta.Position.Zoom = self.defaultzoom
self.requesta.Speed.Zoom = self.zoom_speed
self.ptz.AbsoluteMove(self.requesta)
print('finish absolute_move')
else:
print('default is False, do not perform absolute move')
# reset
self.default = False
self.defaultx = None
self.defaulty = None
self.defaultzoom = None
self.zoomflag = 0
def getCurrentStatus(self):
#获取当前位置信息
pantilt = self.res['Position']['PanTilt']
zoom = self.res['Position']['Zoom']
cx = pantilt['x']
cy = pantilt['y']
cz = zoom['x']
return (cx, cy, cz)
测试脚本
from camera_zoom import CameraZoom
cam = CameraZoom()
for i in range(100):
num = int(input("2:down, 4:left, 8:up, 6:right, 1:enlarge, 3:shrink -> "))
if num == 2:
cam.preformRelativeMove(0, -0.04, 0)
elif num == 4:
cam.preformRelativeMove(-0.04, 0, 0)
elif num == 6:
cam.preformRelativeMove(0.04, 0, 0)
elif num == 8:
cam.preformRelativeMove(0, 0.04, 0)
elif num == 1:
cam.preformRelativeMove(0, 0, 0.02)
elif num == 3:
cam.preformRelativeMove(0, 0, -0.02)
else:
break
其他相关代码
import time
from onvif import ONVIFCamera
import zeep
import requests
from requests.auth import HTTPDigestAuth
def zeep_pythonvalue(self, xmlvalue):
return xmlvalue
def continuous_move():
x = 0#0.001 # 360 : (left)-1 ~ +1(right)
y = -0.004 # 180 : (up)-1 ~ +1(down)
zoom = 0#0.02 # (min)0 ~ 1(max)
mycam = ONVIFCamera("172.22.49.9", 80, "abcd", "wl123456")
# Create media service object
media = mycam.create_media_service()
# Create ptz service object
ptz = mycam.create_ptz_service()
# Get target profile
zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
media_profile = media.GetProfiles()[0]
# Get PTZ configuration options for getting continuous move range
config = ptz.create_type('GetConfigurationOptions')
config.ConfigurationToken = media_profile.PTZConfiguration.token
ptz_configuration_options = ptz.GetConfigurationOptions(config)
request = self.ptz.create_type('ContinuousMove')
request.ProfileToken = media_profile.token
ptz.Stop({'ProfileToken': media_profile.token})
if request.Velocity is None:
request.Velocity = self.ptz.GetStatus({'ProfileToken': media_profile.token}).Position
request.Velocity.PanTilt.space = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].URI
request.Velocity.Zoom.space = ptz_configuration_options.Spaces.ContinuousZoomVelocitySpace[0].URI
#持续移动
request.Velocity.PanTilt.x = x
request.Velocity.PanTilt.y = y
request.Velocity.Zoom = zoom
ptz.ContinuousMove(request)
time.sleep(timeout)
ptz.Stop({'ProfileToken': request.ProfileToken})
print('finish continuous_move')
def relative_move():
x = 0#0.004 # 360 : (left)-1 ~ +1(right)
x_speed = 1
y = 0.004 # 180 : (up)-1 ~ +1(down)
y_speed = 1
zoom = 0#0.02 # (min)0 ~ 1(max)
zoom_speed = 1
mycam = ONVIFCamera("172.22.49.9", 80, "abcd", "wl123456")
# Create media service object
media = mycam.create_media_service()
# Create ptz service object
ptz = mycam.create_ptz_service()
# Get target profile
zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
media_profile = media.GetProfiles()[0]
# Get PTZ configuration options for getting continuous move range
config = ptz.create_type('GetConfigurationOptions')
config.ConfigurationToken = media_profile.PTZConfiguration.token
ptz_configuration_options = ptz.GetConfigurationOptions(config)
requestr = ptz.create_type('RelativeMove')
requestr.ProfileToken = media_profile.token
ptz.Stop({'ProfileToken': media_profile.token})
if requestr.Translation is None:
requestr.Translation = ptz.GetStatus({'ProfileToken': media_profile.token}).Position
requestr.Translation.PanTilt.space = ptz_configuration_options.Spaces.RelativePanTiltTranslationSpace[0].URI
requestr.Translation.Zoom.space = ptz_configuration_options.Spaces.RelativeZoomTranslationSpace[0].URI
if requestr.Speed is None:
requestr.Speed = ptz.GetStatus({'ProfileToken': media_profile.token}).Position
requestr.Speed.PanTilt.space = ptz_configuration_options.Spaces.RelativePanTiltTranslationSpace[0].URI
requestr.Speed.Zoom.space = ptz_configuration_options.Spaces.RelativeZoomTranslationSpace[0].URI
#相对移动
requestr.Translation.PanTilt.x = x
requestr.Speed.PanTilt.x = x_speed
requestr.Translation.PanTilt.y = y
requestr.Speed.PanTilt.y = y_speed
requestr.Translation.Zoom = zoom
requestr.Speed.Zoom = zoom_speed
ptz.RelativeMove(requestr)
print('finish relative_move')
#坐标跳转
def absolute_move():
x = -0.415 # 360 : (left)-1 ~ +1(right)
x_speed = 2
y = -0.374 # 180 : (up)-1 ~ +1(down)
y_speed = 2
zoom = 0.4 # (min)0 ~ 1(max)
zoom_speed = 1
mycam = ONVIFCamera("172.22.49.9", 80, "abcd", "wl123456")
# Create media service object
media = mycam.create_media_service()
# Create ptz service object
ptz = mycam.create_ptz_service()
# Get target profile
zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
media_profile = media.GetProfiles()[0]
# Get PTZ configuration options for getting continuous move range
config = ptz.create_type('GetConfigurationOptions')
config.ConfigurationToken = media_profile.PTZConfiguration.token
ptz_configuration_options = ptz.GetConfigurationOptions(config)
request = ptz.create_type('AbsoluteMove')
request.ProfileToken = media_profile.token
ptz.Stop({'ProfileToken': media_profile.token})
if request.Position is None:
request.Position = ptz.GetStatus({'ProfileToken': media_profile.token}).Position
request.Position.PanTilt.space = ptz_configuration_options.Spaces.AbsolutePanTiltPositionSpace[0].URI
request.Position.Zoom.space = ptz_configuration_options.Spaces.AbsoluteZoomPositionSpace[0].URI
if request.Speed is None:
request.Speed = ptz.GetStatus({'ProfileToken': media_profile.token}).Position
request.Speed.PanTilt.space = ptz_configuration_options.Spaces.AbsolutePanTiltPositionSpace[0].URI
request.Speed.Zoom.space = ptz_configuration_options.Spaces.AbsoluteZoomPositionSpace[0].URI
request.Position.PanTilt.x = x
request.Speed.PanTilt.x = x_speed
request.Position.PanTilt.y = y
request.Speed.PanTilt.y = y_speed
request.Position.Zoom = zoom
request.Speed.Zoom = zoom_speed
ptz.AbsoluteMove(request)
print('finish absolute_move')
#抓图
def snap():
# Get target profile
zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
mycam = ONVIFCamera("172.22.49.9", 80, "abcd", "wl123456")
media = mycam.create_media_service() # 创建媒体服务
media_profile = media.GetProfiles()[0] # 获取配置信息
res = media.GetSnapshotUri({'ProfileToken': media_profile.token})
response = requests.get(res.Uri, auth=HTTPDigestAuth("zhy", "zhy12345"))
res = "{_time}.jpg".format(_time=time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time())))
with open(res, 'wb') as f: # 保存截图
f.write(response.content)
#预置位跳转
def gotoPreset():
zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
mycam = ONVIFCamera("172.22.49.9", 80, "abcd", "wl123456")
media = mycam.create_media_service()
ptz = mycam.create_ptz_service()
params = ptz.create_type('GotoPreset')
media_profile = media.GetProfiles()[0] # 获取配置信息
print(media_profile.token)
params.ProfileToken = media_profile.token
params.PresetToken = 1
re = ptz.GotoPreset(params)
print(re)
#获取当前位置信息
def getStatus():
mycam = ONVIFCamera("172.22.49.9", 80, "abcd", "wl123456")
media = mycam.create_media_service()
ptz = mycam.create_ptz_service()
zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
media_profile = media.GetProfiles()[0] # 获取配置信息
params = ptz.create_type('GetStatus')
print(f"media_profile.token is {media_profile.token}")
params.ProfileToken = media_profile.token
res = ptz.GetStatus(params)
print(f"res is {res}")
if __name__ == '__main__':
# absolute_move()
# snap()
# gotoPreset()
relative_move()
getStatus()