I am trying to do a share screen using python and pygame, and the screenshots I take with d3dshot. Does anyone have an idea How can I make it better and increase the frames per second?
This is my code: Server - share the screen with the client
""" Server """
from socket import socket
from threading import Thread
import pyautogui
import cv2
import numpy as np
import d3dshot
from lz4.frame import compress
WIDTH, HEIGHT = pyautogui.size()
def retreive_screenshot(conn):
d = d3dshot.create(capture_output="numpy")
while 'recording':
img = d.screenshot()
img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)
img = compress(img, 10)
# Send the size of the pixels length
size = len(img)
size_len = (size.bit_length() + 7) // 8
conn.send(bytes([size_len]))
# Send the actual pixels length
size_bytes = size.to_bytes(size_len, 'big')
conn.send(size_bytes)
# Send pixels
conn.sendall(img)
def main(host='0.0.0.0', port=5000):
sock = socket()
sock.bind((host, port))
try:
sock.listen(5)
print('Server started.')
while 'connected':
conn, addr = sock.accept()
print('Client connected IP:', addr)
thread = Thread(target=retreive_screenshot, args=(conn,))
thread.start()
finally:
sock.close()
if __name__ == '__main__':
main()
Client - get the screen from the server and show the server screen
""" Client """
from socket import socket
from lz4.frame import decompress
import numpy as np
import pygame
import cv2
WIDTH = 1600
HEIGHT = 900
def recvall(conn, length):
""" Retreive all pixels. """
buf = b''
while len(buf) < length:
data = conn.recv(length - len(buf))
if not data:
return data
buf += data
return buf
def main(host='127.0.0.1', port=5000):
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
watching = True
sock = socket()
sock.connect((host, port))
try:
while watching:
for event in pygame.event.get():
if event.type == pygame.QUIT:
watching = False
break
# Retreive the size of the pixels length, the pixels length and pixels
size_len = int.from_bytes(sock.recv(1), byteorder='big')
size = int.from_bytes(sock.recv(size_len), byteorder='big')
img = decompress(recvall(sock, size))
img = np.frombuffer(img, np.uint8)
img = img.reshape((int(HEIGHT * 0.5), -1, 3))
img = cv2.resize(img, (0, 0), fx=2, fy=2).tobytes()
# Create the Surface from raw pixels
img = pygame.image.fromstring(img, (WIDTH, HEIGHT), 'RGB')
# Display the picture
screen.blit(img, (0, 0))
pygame.display.flip()
finally:
sock.close()
if __name__ == '__main__':
main()