我正在开发一个与Twitch(https://www.twitch.tv/)类似的python项目。 问题是我用tkinter显示图像,用pyaudio显示音频,只有音频可以工作。 有人有主意吗?
我尝试检查数据是否实际发送,并发现它已发送。但是,您只能听到音频而看不到图像。我不知道是什么问题。
"""
Server code
"""
import pyaudio
from socket import socket, error
from threading import Thread
from PIL import Image
from mss import mss
from io import BytesIO
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
IP = '0.0.0.0'
PORT = 5000
MONITOR = {"top": 200, "left": 800, "width": 600, "height": 500}
SCREEN_PROTOCOL = 'S'
MICROPHONE_PROTOCOL = 'M'
class Server(object):
def __init__(self, ip, port, chunk, format1, channels, rate, monitor):
self.sock = socket()
self.sock.bind((ip, port))
self.conn = None
self.monitor = monitor
self.chunk = chunk
self.format = format1
self.channels = channels
self.rate = rate
self.p = pyaudio.PyAudio()
self.stream = self.p.open(format=self.format, channels=self.channels,
rate=self.rate, input=True, frames_per_buffer=self.chunk)
self.data = ''
def send_data(self, data):
# Send the size of the pixels length
size = len(data)
size_len = (size.bit_length() + 7) // 8
print('size len: ' + str(size_len))
self.conn.send(bytes([size_len]))
# Send the actual pixels length
size_bytes = size.to_bytes(size_len, 'big')
self.conn.send(size_bytes)
print('size: ' + str(size))
# Send pixels
self.conn.sendall(data)
def send_all(self):
while True:
with mss() as sct:
screen = sct.grab(self.monitor)
im = Image.frombytes('RGB', (600, 500), screen.rgb)
buf = BytesIO()
im.save(buf, format='JPEG', quality=75)
self.data = buf.getvalue()
self.send_data(self.data)
self.data = self.stream.read(self.chunk)
self.send_data(self.data)
def start(self):
self.sock.listen(5)
print('Server started.')
while True:
self.conn, addr = self.sock.accept()
print('Client connected IP:', addr)
t = Thread(target=self.send_all)
t.start()
def close_connection(self):
self.sock.close()
def main():
"""
Add Documentation here
"""
server = Server(IP, PORT, CHUNK, FORMAT, CHANNELS, RATE, MONITOR)
try:
server.start()
except error as msg:
print(msg)
finally:
server.close_connection()
if __name__ == '__main__':
main()
"""
Client code
"""
import pyaudio
from socket import socket, error
from io import BytesIO
from PIL import Image, ImageTk
import tkinter
IP = '127.0.0.1'
PORT = 5000
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
WIDTH = 600
HEIGHT = 500
class Client:
def __init__(self, ip, port, width, height, chunk, format1, channels, rate):
self.sock = socket()
self.sock.connect((ip, port))
self.root = tkinter.Tk()
self.size = str(width) + 'x' + str(height)
self.root.geometry(self.size)
self.panel = None
self.protocol = ''
self.chunk = chunk
self.format = format1
self.channels = channels
self.rate = rate
self.p = pyaudio.PyAudio()
self.stream = self.p.open(format=self.format, channels=self.channels,
rate=self.rate, output=True, frames_per_buffer=self.chunk)
self.data = ''
def recvall(self, length):
""" Retreive all pixels. """
buf = b''
while len(buf) < length:
data = self.sock.recv(length - len(buf))
if not data:
return data
buf += data
return buf
def recv_and_display(self):
print('screen shot')
size_len = int.from_bytes(self.sock.recv(1), byteorder='big')
print('size len: ' + str(size_len))
size = int.from_bytes(self.sock.recv(size_len), byteorder='big')
print('size: ' + str(size))
self.data = self.recvall(size)
# Create the Surface from raw pixels
buf = BytesIO()
buf.write(self.data)
img = Image.open(buf).convert('RGB')
tk_img = ImageTk.PhotoImage(image=img)
if self.panel is None:
print('a')
self.panel = tkinter.Label(self.root, image=tk_img)
self.panel.pack(side="bottom", fill="both", expand="yes")
else:
print('b')
self.panel.configure(image=tk_img)
print('audio')
size_len = int.from_bytes(self.sock.recv(1), byteorder='big')
print('size len: ' + str(size_len))
size = int.from_bytes(self.sock.recv(size_len), byteorder='big')
print('size: ' + str(size))
self.data = self.recvall(size)
self.stream.write(self.data)
self.root.after(1, self.recv_and_display)
def start(self):
self.root.after(1, self.recv_and_display)
self.root.mainloop()
def close_connection(self):
self.stream.stop_stream()
self.stream.close()
self.p.terminate()
self.sock.close()
def main():
"""
Add Documentation here
"""
stream_client = Client(IP, PORT, WIDTH, HEIGHT, CHUNK, FORMAT, CHANNELS, RATE)
try:
stream_client.start()
except error as msg:
print(msg)
finally:
stream_client.close_connection()
if __name__ == '__main__':
main()
我希望音频和图像都将显示在客户端。