Loading... # 一台电脑当服务器多线程提供摄像头服务,支持多台电脑调用 # 一、效果展示 ## 和舍友联机,多台电脑效果 **用一个电脑当服务端,舍友当客户端连接** **监控寝室外面的情况** **客户端需要使用命令行调用** ![](http://type.zimopy.com/usr/uploads/2023/02/3769887470.png) # 二、带注释的代码 ## 1.服务端 ```python import time import socket import cv2 import numpy as np import sys from threading import Thread def get_cam(): '''这是从电脑摄像机获取视频的函数''' capture = cv2.VideoCapture(0) while True: ret, frames = capture.read() # ret为返回值,frame为视频的每一帧 yield frames cv2.imshow('the video in local',frames) c = cv2.waitKey(50) return frames class Server(): def __init__(self,frames,name): '''初始化函数''' super().__init__() #表明该进程的名字 self.name = name # 服务器本地地址 # 初始化服务器 self.udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #self.udp_socket = self.udp_socket.bind(addr) self.frames = frames def post_cam(self,frame,addr): '''这是将视频广播出去的函数''' frame=cv2.resize(frame,(360,260)) #控制画面大小 img_encode = cv2.imencode('.jpg', frame)[1] data_encode = np.array(img_encode) data = data_encode.tobytes() self.udp_socket.sendto(data,addr) def log_save(self): '''由客户端得到具体信息,写入日志''' data,addr = self.udp_socket.recvfrom(1024) Note=open(f'{self.name}.txt',mode='w') Note.writelines('ip'+str(addr)+data) def run(self): addr = {'张':('192.168.236.27',8080),'向':('192.168.236.198',8080),'杨':('127.0.0.3',8080)} for frame in self.frames: self.post_cam(frame, addr['张']) self.post_cam(frame, addr['向']) self.post_cam(frame, addr['杨']) print(f'{self.name}的线程成功启动!') if __name__ == "__main__": frames = get_cam() #调用本机的摄像机,只需一次,不用写入线程 S = Server(frames,'123') S.run() ``` ## 2.客户端 还支持保存传输来的视频,记录日志文件等功能 ```python import socket import cv2 import sys import time import datetime import getpass import numpy as np class Individual(): def __init__(self,addr): '''初始化函数''' self.address = addr def log(self): '''创建日志''' #s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) user = getpass.getuser() #获取连接者的用户名 now_time = datetime.datetime.now().strftime('%F %T') data = f'user{user} in {now_time}use the monitor' #s.sendto(data.encode("utf-8"),addr) Note=open(f'{user}.txt',mode='w') Note.writelines('ip'+str(self.address)+data) def receive_save(self): '''接受发送的视频,并且保存到本地''' s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(self.address) #下面这部分是发送日志内容 # user = getpass.getuser() #获取连接者的用户名 # now_time = datetime.datetime.now().strftime('%F %T') # data = f'用户{user}在{now_time}调用了监控' # s.sendto(data.encode("utf-8"),addr) #下面开始视频展示 imgs = [] while True: data, addr = s.recvfrom(400000) nparr = np.frombuffer(data, np.uint8) img_decode = cv2.imdecode(nparr, cv2.IMREAD_COLOR) cv2.startWindowThread() cv2.imshow('receive',img_decode) #视频展示 c = cv2.waitKey(50) if c == 27: # 按了esc候可以退出 break #一帧一帧保存图片成视频 imgs.append(img_decode) v=cv2.VideoWriter(f'D:/cam.avi',\ cv2.VideoWriter_fourcc(*'MJPG'),5,(360,300)) for i in imgs: i = cv2.resize(i,(360,300)) v.write(i) def run(self): self.log() self.receive_save() if __name__ == '__main__': addr=(sys.argv[1], int(sys.argv[2])) use = Individual(addr) use.run() ``` 最后修改:2023 年 02 月 13 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏