此文紧接:juejin.cn/post/710182… 展开
情况一:项目和相机在同一网段
创建.py文件命名为:Config,构造一个通过数据库查询相机的ip,username, password 的类,方便连取相机时获取相机的ip,username, password问题。
Config.py具体如下所示:
import pymysql
class BaseSet():
# 连接数据库基础参数
def __init__(self):
# 连接数据库
self.conn = pymysql.connect(host='localhost' # 连接名称,默认127.0.0.1
, user='root' ## 用户名
, passwd='root' # 密码
, port=3306 # 端口,默认为3306
, db='camera' # 数据库名称
, charset='utf8' # 字符编码
)
self.cur = self.conn.cursor() # 生成游标对象
# Sql语句
self.ConstructionSql = 'SELECT ip,username, password FROM cameras'
def GetCamIDInfo(self):
try:
self.cur.execute(self.ConstructionSql) # 执行插入的sql语句
return self.cur.fetchall()
except:
self.conn.commit() # 提交到数据库执
复制代码
创建.py文件命名为demo,这里将是你链接相机播放视频画面的核心部分了,这里我们将涉及多进程读取相机播放视频画面.
import multiprocessing
from Config import BaseSet
import cv2
def GetInfolIST():
Config = BaseSet()
IpList = []
UsernameList = []
PasswordList = []
for ip, username, password in Config.GetCamIDInfo():
IpList.append(ip)
UsernameList.append(username)
PasswordList.append(password)
return IpList, UsernameList, PasswordList
def SaveFrams(username, password, ip):
rtsp = "rtsp://%s:%s@%s:554/cam/realmonitor?channel=1&subtype=1" % (username, password, ip)
cap = cv2.VideoCapture(rtsp)
if cap.isOpened():
ret, frame = cap.read() # read_latest_frame() 替代 read()
if ret:
print("Can receive frame. Starting ..")
cv2.imshow("video-%s" %ip, frame)
else:
cap.release()
if __name__ == '__main__':
IpList, UsernameList, PasswordList = GetInfolIST()
while True:
p = multiprocessing.Pool(5)
r_list = []
for username, password, ip in zip(UsernameList, PasswordList, IpList):
r_list.append(p.apply_async(SaveFrams, args=(username, password, ip)))
p.close()
for r in r_list:
r.get()
复制代码
情况二:项目和相机不在同一网段
这里我们沿用情况一中获取ip,username, password结果,更改为获取相机indexcode。这里文件命名为: ConfigMysql.py 代码部分如下:
import pymysql
class BaseSetMySql():
# 连接数据库基础参数
def __init__(self):
# 连接数据库
self.conn = pymysql.connect(host='localhost' # 连接名称,默认127.0.0.1
, user='root' ## 用户名
, passwd='root' # 密码
, port=3306 # 端口,默认为3306
, db='CamIndexcode' # 数据库名称
, charset='utf8' # 字符编码
)
self.cur = self.conn.cursor() # 生成游标对象
# Sql语句
self.Sql = 'SELECT indexcode FROM indexcodes'
# 获取摄像机编码
def GetCamID(self):
try:
self.cur.execute(self.Sql) # 执行插入的sql语句
CamID = self.cur.fetchall()
return CamID
except:
self.conn.commit() # 提交到数据库执
复制代码
创建ConfigRTSP.py文件用来通过indexcode发送请求获取RTSP
import requests
class BaseSetRTSP():
def __init__(self):
self.UrlIndexCode = 'http://localhost:8090/Hikvision/previewURLs'
# 获取RTSP
def GetRTSP(self, CamId):
data = {'cameraIndexCode': CamId}
RestData = requests.post(self.UrlIndexCode, data=data)
RestDataDict = RestData.json()
RTSP = None
RightInfo = "rtsp" in str(RestDataDict)
if RightInfo is True:
Data_RestDataDict = ((eval(RestDataDict['data']))['data'])
RTSP = Data_RestDataDict['url']
return RTSP
复制代码
创建ConfigFrame.py用来播放视频画面,代码如下:
import uuid
import cv2
import os
os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;udp"
class BaseSetSaveFrame():
def __init__(self):
pass
#
def PlayFrame(self, CAMID, RTSP):
cap = cv2.VideoCapture(rtsp)
if cap.isOpened():
ret, frame = cap.read() # read_latest_frame() 替代 read()
if ret:
print("Can receive frame. Starting ..")
cv2.imshow("video-%s" %CAMID, frame)
else:
cap.release()
复制代码
**接下来就是调用上面的类进行获取相机画面了,在此之前需要将上述的三个文件放置在一个名为ImagesConfig的文件夹中。调用代码如下:
import multiprocessing
from ImagesConfig.ConfigMysql import BaseSetMySql
from ImagesConfig.ConfigRTSP import BaseSetRTSP
from ImagesConfig.ConfigSaveFrame import BaseSetSaveFrame
# 整体流程:播放裸土图像
def PlayCamsImgs():
ConfigMysql = BaseSetMySql()
ConfigRTSP = BaseSetRTSP()
AllCamId = ConfigMysql.GetCamID()
for CamIdName in AllCamId:
ListCamIds = list(CamIdName)
CamId = ' '.join(str(i) for i in ListCamIds)
RTSP = ConfigRTSP.GetRTSPCamId)
if RTSP is not None:
print("正在连接此RTSP:", RTSP)
ConfigSaveFrame = BaseSetSaveFrame()
ConfigSaveFrame.PlayFrame(CamId, RTSP)
if __name__ == '__main__':
PlayCamsImgs()
复制代码