我想使用Python中的套接字编程流式传输网络摄像头提要 [英] I want to stream a webcam feed using socket programming in Python
问题描述
这是我的代码:
#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()
客户端。 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...
在没有套接字的情况下实现的工作代码:camcapture.py
Working code when implemeted without sockets: 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()
错误是:
image = pygame.image.fromstring(data,(640,480),"RGB")
ValueError: String length does not equal format and resolution size
我在哪里出错了?
推荐答案
问题不在于相机。
问题是您在套接字上发送了一个非常大的字符串,并且错误地认为可以使用 conn一次读取整个字符串。 recv(921637)
。
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)
.
您必须多次调用 recv
才能接收全部数据。尝试打印在 client.py
中发送的 data
的长度,并打印 data的长度调用
,您会看到的。 pygame.image.fromstring
之前的 server.py
中的
You'll have to call recv
multiple times to receive all over your data. 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.
有几种解决方法:
- 为您发送的每张图片
- 发送数据的大小,以便服务器知道要读取多少数据
- 使用某种结束标记 >
- 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
这是一个简单的示例:
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()
这篇关于我想使用Python中的套接字编程流式传输网络摄像头提要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!