zoukankan      html  css  js  c++  java
  • udp 视频传输 python

    根据UDP协议,从UDP数据包的包头可以看出,UDP的最大包长度是2^16-1的个字节。由于UDP包头占8个字节,而在IP层进行封装后的IP包头占去20字节,所以这个是UDP数据包的最大理论长度是2^16 - 1 - 8 - 20 = 65507字节。如果发送的数据包超过65507字节,send或sendto函数会错误码1(Operation not permitted, Message too long)

    当视频分辨率(长*宽<65507时)

    接收视频端:

    import cv2
    from socket import *
    from time import ctime, sleep
    import threading
    import numpy as np
    
    class ChatRoomPlus:
        def __init__(self):
            # 全局参数配置
            self.encoding = "utf-8"  # 使用的编码方式
            self.recvbroadcastPort = 10101  # 广播端口
            self.sendbroadcastPort = 10102
    
            # 创建广播接收器
            self.recvSocket = socket(AF_INET, SOCK_DGRAM)
            self.recvSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
            self.recvSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
            self.recvSocket.bind(('', self.recvbroadcastPort))
    
            # 创建广播发送器
            self.sendSocket = socket(AF_INET, SOCK_DGRAM)
            self.sendSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
            self.sendData=None
            # 其他
            self.threads = []
    
        def send(self):
            """发送广播"""
            self.sendData = "1"
            print("UDP发送器启动成功...")
            while True:
    
                self.sendSocket.sendto(self.sendData.encode(self.encoding), ('255.255.255.255', self.sendbroadcastPort))
                #print("【%s】%s:%s" % (ctime(), "", self.sendData))
    
                #sleep(1)
            self.sendSocket.close()
    
        def recv(self):
            """接收广播"""
    
            print("UDP接收器启动成功...")
            cv2.namedWindow('img')
            while True:
                # 接收数据格式:(data, (ip, port))
                recvData, addr = self.recvSocket.recvfrom(400000)
                recvData = np.frombuffer(recvData, dtype=np.uint8)
                if recvData[0]:
                    imde = cv2.imdecode(recvData, 1)
                    print("imshow........")
                    cv2.imshow('img', imde)
                    k = cv2.waitKey(1)
                    if k == ord('q'):
                        self.sendData="0"
                        break
    
               # sleep(1)
            self.recvSocket.close()
            cv2.destroyAllWindows()
    
    
    
        def start(self):
            """启动线程"""
    
            t1 = threading.Thread(target=self.recv)
            t2 = threading.Thread(target=self.send)
            self.threads.append(t1)
            self.threads.append(t2)
    
            for t in self.threads:
                t.setDaemon(True)
                t.start()
    
            while True:
                pass
    
    
    if __name__ == "__main__":
        demo = ChatRoomPlus()
        demo.start()

    视频发送端:

    import cv2
    from socket import *
    from time import ctime, sleep
    import threading
    
    
    class ChatRoomPlus:
        def __init__(self):
            # 全局参数配置
            self.encoding = "utf-8"  # 使用的编码方式
            self.recvbroadcastPort = 10102   # 广播端口
            self.sendbroadcastPort = 10101
            # 创建广播接收器
            self.recvSocket = socket(AF_INET, SOCK_DGRAM)
            self.recvSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
            self.recvSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
            self.recvSocket.bind(('', self.recvbroadcastPort))
            self.recvData=None
    
            # 创建广播发送器
            self.sendSocket = socket(AF_INET, SOCK_DGRAM)
            self.sendSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
    
    
    
            # 其他
            self.threads = []
    
        def send(self):
            """发送广播"""
            cap = cv2.VideoCapture('ex2.mp4')
            # cap.set(3, 224)
            # cap.set(4, 224)
            print("UDP发送器启动成功...")
    
            while True:
                print(self.recvData)
                if self.recvData == b'1':
                    ret, fra = cap.read()
                    if ret:
                        print(ret)
                        _, sendData = cv2.imencode('.jpg', fra)
                        print(sendData.size)
                        print(fra.size)
                        self.sendSocket.sendto(sendData, ('255.255.255.255', self.sendbroadcastPort))
    
                sleep(1)
            self.sendSocket.close()
            cap.release()
    
        def recv(self):
            """接收广播"""
    
            print("UDP接收器启动成功...")
            while True:
                # 接收数据格式:(data, (ip, port))
                self.recvData, addr = self.recvSocket.recvfrom(1024)
    
                # print("【%s】[%s : %s] : %s" % (ctime(), self.recvData[1][0], self.recvData[1][1], self.recvData[0].decode(self.encoding)))
    
                #sleep(1)
            self.recvSocket.close()
    
        def start(self):
            """启动线程"""
    
            t1 = threading.Thread(target=self.recv)
            t2 = threading.Thread(target=self.send)
            self.threads.append(t1)
            self.threads.append(t2)
    
            for t in self.threads:
                t.setDaemon(True)
                t.start()
    
            while True:
                pass
    
    
    if __name__ == "__main__":
        demo = ChatRoomPlus()
        demo.start()

    参考:https://www.cnblogs.com/purpleraintear/p/6403053.html

    https://bbs.csdn.net/topics/392314197?page=1

    https://www.cnblogs.com/reader/p/10011666.html

  • 相关阅读:
    5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
    5.15 省选模拟赛 容斥 生成函数 dp
    5.15 省选模拟赛 T1 点分治 FFT
    5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制
    luogu P4929 【模板】舞蹈链 DLX
    CF 878E Numbers on the blackboard 并查集 离线 贪心
    5.10 省选模拟赛 拍卖 博弈 dp
    5.12 省选模拟赛 T2 贪心 dp 搜索 差分
    5.10 省选模拟赛 tree 树形dp 逆元
    luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
  • 原文地址:https://www.cnblogs.com/cekong/p/11419880.html
Copyright © 2011-2022 走看看