利用VideoCapture進行遠程視頻傳輸

看了一個基於python的高速視頻傳輸程序發現挺有意思的。就自己仿照寫了一個,,,,大笑

需要用到的擴展包有:

PIL(Pillow),                  處理圖片

VideoCapture,            調用攝像頭截圖

Pygame                       圖片的顯示

上面的擴展可以從http://www.lfd.uci.edu/~gohlke/pythonlibs/  獲得


運行環境:Py3.3


服務端代碼:

from VideoCapture import Device;
import socket;
import threading;
import struct;
class webCamera:
    def __init__(self, resolution = (640, 480), host = ("", 8000)):
        self.resolution = resolution;
        self.host = host;
        self.video = Device();
        self.setSocket(self.host);
        
    def setImageResolution(self, resolution):
        self.resolution = resolution;
        
    def setHost(self, host):
        self.host = host;
        
    def setSocket(self, host):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        self.socket.bind(self.host);
        self.socket.listen(5);
        print("Server running on port:%d" % host[1]);
        
    def _processConnection(self, client,addr):
        print("Got connection from %s:%d" % (addr[0], addr[1]));
        while(1):
            self.img = self.video.getImage();
            self.imgdata = self.img.resize(self.resolution).tostring();
            try:
                client.send(struct.pack("lhh", len(self.imgdata), self.resolution[0], self.resolution[1]) + self.imgdata); #發送圖片信息(圖片長度,分辨率,圖片內容)
            except ConnectionResetError:
                print("%s:%d disconnected!" % (addr[0], addr[1]));
                return;
                
    def run(self):
        while(1):
            client,addr = self.socket.accept();
            clientThread = threading.Thread(target = self._processConnection, args = (client, addr, ));  #有客戶端連接時產生新的線程進行處理
            clientThread.start();
def main():
    cam = webCamera();
    cam.run();
if __name__ == "__main__":
    main();

客戶端代碼:


import pygame;
import socket;
import threading;
from PIL import Image;
import struct;
import os;
import time;
import sys;
class webCamConnect:
    def __init__(self, resolution = (640, 480), remoteAddress = ("127.0.0.1", 8000), windowName = "Demo"):
        self.remoteAddress = remoteAddress;
        self.resolution = resolution;
        self.name = windowName;
        self.mutex = threading.Lock();

    def _setSocket(self):
        self.socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);

    def connect(self):
        self._setSocket();
        self.socket.connect(self.remoteAddress);
    
    def _initWindow(self):
        pygame.init();
        screen = pygame.display.set_mode(self.resolution);
        pygame.display.set_caption(self.name);
        return screen;

    def _processImage(self):
        screen = self._initWindow();
        while(1):
            info = struct.unpack("lhh",self.socket.recv(8));
            bufSize = info[0];
            if bufSize:
                try:
                    self.mutex.acquire();
                    self.buf=bytes(0,"little");
                    tempBuf=self.buf;
                    while(bufSize):                 #循環讀取到一張圖片的長度
                        tempBuf = self.socket.recv(bufSize);
                        bufSize -= len(tempBuf);
                        self.buf += tempBuf;
                    self.image = pygame.image.frombuffer(self.buf, (info[1], info[2]), "RGB");
                    for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                            return;
                    screen.blit(self.image, (0, 0));
                    pygame.display.update(); 
                except:
                    pass;
                finally:
                    self.mutex.release();

    def getData(self, interval = -1):  
        showThread=threading.Thread(target=self._processImage);
        showThread.start();
        if interval != -1:   # 非-1則啓動保存截圖到本地的功能
            saveThread=threading.Thread(target=self._savePicToLocal,args = (interval, ));
            saveThread.setDaemon(1);
            saveThread.start();

    def setWindowName(self, name):
        self.name = name;

    def setRemoteAddress(remoteAddress):
        self.remoteAddress = remoteAddress;

    def _savePicToLocal(self, interval):
        while(1):
            try:
                self.mutex.acquire();
                path=os.getcwd() + "\\" + "savePic";
                if not os.path.exists(path):
                    os.mkdir(path);
                image=Image.frombytes("RGB", self.resolution, self.buf);
                image.save(path + "\\" + time.strftime("%Y%m%d-%H%M%S", time.localtime(time.time())) + ".jpg");
            except:
                pass;
            finally:
                self.mutex.release();
                time.sleep(interval);

def main():
    cam = webCamConnect();
    cam.connect();
    cam.getData();
if __name__ == "__main__":
    main();

運行截圖:


服務端:



客戶端:(多個窗口)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章