2025年5月17日 星期六 乙巳(蛇)年 二月十九 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

python实现基于UDP的视频直播程序

时间:03-17来源:作者:点击数:54

最近在看线性代数和概率论,有点无聊,于是自己做了一个视频传输程序放松一下

TCP和UDP两种协议这里选用UDP协议,主要因为TCP在传输的时候会产生沾包的状况,而UDP不会有这种问题

1.视频信息的采集

对于摄像头,使用OpenCV打开并获取每一帧的图像,将其封装成字节流进行传输

获取摄像头视频流

  • cam = cv2.VideoCapture(0) #打开摄像头
  • while (cam.isOpened()):
  • ret,frame = cam.read() #获取视频流

这一步没啥好说的,最基本的API调用

对每一帧图像进行处理

将每一帧图像写入内存(与写入文件类似),然后读出为字节用于网络传输.可以想象为先将每一帧图像都保存为文件,再发送文件,不过写入文件太慢,这里直接写入内存

  • def array_pic_to_stream(pic):
  • stream = BytesIO()
  • pic = Image.fromarray(pic)
  • pic.save(stream, format="JPEG")
  • jepg = stream.getvalue()
  • stream.close()
  • return jepg

可以将BytesIO理解为一个保存在内存中的文件,通过写入,写出操作将numpy.array()类型数据转化为二进制文件

对于屏幕,使用Image的截图功能截取每一帧图像,将其封装成字节流

获取视频流

  • img = ImageGrab.grab()
  • out = img.resize((612,480))

这里要注意,之所以对图片的大小进行削减是因为UDP传输的包的大小是有限制的,好像是六万五左右,而屏幕分辨率太高,所以 必须缩减

对每一帧图像进行处理

将Image对象转化为数组,在转化为字节流

  • def pic_to_array(pic):
  • stram = BytesIO()
  • pic.save(stram, format="JPEG")
  • array_pic = numpy.array(Image.open(stram))
  • stram.close()
  • return array_pic
  • def array_pic_to_stream(pic):
  • stream = BytesIO()
  • pic = Image.fromarray(pic)
  • pic.save(stream, format="JPEG")
  • jepg = stream.getvalue()
  • stream.close()
  • return jepg

2.发送

这一步基本没什么区别,直接构建socket发送即可

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.sendto(jepg,address)

3.接收段端

发送端的反向逻辑,没什么好说的

  • def receive(process=None):
  • sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  • sock.bind(address)
  • while True:
  • img,addr= sock.recvfrom(1024*1024)
  • buf = BytesIO(img)
  • img = numpy.array(Image.open(buf))
  • a = Image.open(buf)
  • #a.show()
  • cv2.imshow("receive",img)
  • buf.close()
  • if (cv2.waitKey(1) & 0xFF) == ord('q'):
  • break
  • else:
  • continue
  • cv2.destroyAllWindows

4.测试

最后的用路由器组了一个局域网用我的win板和笔记本进行实验,调用摄像头发现FPS很高,清晰度也不错,基本无延迟

但是测试屏幕直播功能发现因为udp传输包的大小限制,图像失真很严重,基本无法辨认

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门