情况一:项目和相机在同一网段
创建.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()