简体   繁体   English

我想使用Python中的套接字编程来流式传输网络摄像头

[英]I want to stream a webcam feed using socket programming in Python

This is my code: 这是我的代码:

server.py: server.py:

#The server receives the data

import socket
from PIL import Image
import pygame,sys
import pygame.camera
from pygame.locals import *
import time

host = "localhost"
port = 1890
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
conn, addr = s.accept()
print "connected by",addr

screen = pygame.display.set_mode((640,480))

while 1:
        data = conn.recv(921637)
        image = pygame.image.fromstring(data,(640,480),"RGB")
        screen.blit(image,(0,0))
        pygame.display.update()
        if not image: 
               break;
        conn.send(data)
conn.close()

client.py client.py

#The client sends the data

import socket
from PIL import Image
import pygame,sys
import pygame.camera
from pygame.locals import *
import time

host = "localhost"
port = 1890
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))


pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(640,480))
cam.start()

while 1:
        image = cam.get_image()
        data = pygame.image.tostring(image,"RGB")
        s.sendall(data)     

s.close()
print "recieved", repr(data)

Just to test, I tried the following code and it's working fine, but the above does not... 只是为了测试,我尝试了以下代码并且它工作正常,但上面没有......

Working code when implemeted without sockets: camcapture.py 在没有套接字的情况下实现时的工作代码:camcapture.py

import sys
import time
import pygame
import pygame.camera
from pygame.locals import *

pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(640,480))
cam.start()

screen = pygame.display.set_mode((640,480))

while 1:
        image = cam.get_image()
        data = pygame.image.tostring(image,"RGB")
        img = pygame.image.fromstring(data,(640,480),"RGB")
        screen.blit(img,(0,0))
        pygame.display.update()

The error is: 错误是:

image = pygame.image.fromstring(data,(640,480),"RGB")
ValueError: String length does not equal format and resolution size

Where did I go wrong? 我哪里做错了?

The problem is not the camera. 问题不在于相机。

The problem is that you send a very large string over the socket and you incorrectly assume that you can read the entire string at once with conn.recv(921637) . 问题是您在套接字上发送了一个非常大的字符串,并且错误地认为您可以使用conn.recv(921637)一次读取整个字符串。

You'll have to call recv multiple times to receive all over your data. 您必须多次调用recv才能接收所有数据。 Try printing the length of data you send in client.py and print the length of data in server.py before calling pygame.image.fromstring and you'll see. 尝试打印的长度data ,你在发送client.py并打印长度dataserver.py调用之前pygame.image.fromstring ,你会看到。

There are several ways to solve this: 有几种方法可以解决这个问题:

  • make a new connection for each image you send 为您发送的每个图像建立新连接
  • send the size of your data so the server knows how much data to read 发送数据大小,以便服务器知道要读取多少数据
  • use some kind of end marker 使用某种结束标记

Here's a simple example: 这是一个简单的例子:

sender: 发件人:

import socket
import pygame
import time

host = "localhost"
port = 1890
pygame.init()
image = pygame.surface.Surface((640, 480))
i=0
j=0
while 1:
    image.fill((i,j,0))
    i+=10
    j+=5
    if i >= 255: i = 0
    if j >= 255: j = 0
    data = pygame.image.tostring(image,"RGB")
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    s.sendall(data)
    s.close()
    time.sleep(0.5)

receiver: 接收器:

import socket
import pygame

host="localhost"
port=1890

screen = pygame.display.set_mode((640,480))

while 1:
    s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host,port))
    s.listen(1)
    conn, addr = s.accept()
    message = []
    while True:
        d = conn.recv(1024*1024)
        if not d: break
        else: message.append(d)
    data = ''.join(message)
    image = pygame.image.fromstring(data,(640,480),"RGB")
    screen.blit(image,(0,0))
    pygame.display.update()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM