--FastAPI added
This commit is contained in:
george committed 2026-07-17 17:09:16 +05:30
1 parent 6907288be7
commit c52f1eb478
17 files changed
+348 -2

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
from dotenv import load_dotenv
import os
load_dotenv()
ADMIN_API_KEY = os.getenv("ADMIN_API_KEY")
+91
View File
@@ -0,0 +1,91 @@
import signal
import time
from pathlib import Path
import cv2
import numpy as np
from mss import mss
OUTPUT_FILE = Path("screen_recording.avi")
FPS = 20
MONITOR_NUMBER = 1
recording = True
def stop_recording(signum=None, frame=None):
global recording
recording = False
print("\nStopping recording safely...")
signal.signal(signal.SIGINT, stop_recording)
signal.signal(signal.SIGTERM, stop_recording)
def main():
global recording
with mss() as sct:
monitor = sct.monitors[MONITOR_NUMBER]
width = monitor["width"]
height = monitor["height"]
# Video codecs generally prefer even dimensions.
width -= width % 2
height -= height % 2
# MJPG inside AVI is more resistant to corruption than MP4.
fourcc = cv2.VideoWriter_fourcc(*"MJPG")
writer = cv2.VideoWriter(
str(OUTPUT_FILE),
fourcc,
FPS,
(width, height),
)
if not writer.isOpened():
raise RuntimeError("Could not open VideoWriter")
print(f"Recording {width}x{height} at {FPS} FPS")
print("Press Ctrl+C once to stop safely.")
frame_interval = 1.0 / FPS
next_frame_time = time.perf_counter()
try:
while recording:
screenshot = sct.grab(
{
"left": monitor["left"],
"top": monitor["top"],
"width": width,
"height": height,
}
)
frame = np.asarray(screenshot)
frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
writer.write(frame)
next_frame_time += frame_interval
sleep_time = next_frame_time - time.perf_counter()
if sleep_time > 0:
time.sleep(sleep_time)
else:
next_frame_time = time.perf_counter()
finally:
writer.release()
cv2.destroyAllWindows()
print(f"Recording saved safely: {OUTPUT_FILE.resolve()}")
if __name__ == "__main__":
main()
+102
View File
@@ -0,0 +1,102 @@
import socket
import struct
import cv2
import numpy as np
LISTEN_IP = "0.0.0.0"
LISTEN_PORT = 5000
HEADER_SIZE = 4
MAX_FRAME_SIZE = 20 * 1024 * 1024 # 20 MB safety limit
def receive_exact(sock, size):
"""
Receive exactly 'size' bytes.
TCP recv() may return fewer bytes than requested,
so we keep receiving until the full frame arrives.
"""
data = bytearray()
while len(data) < size:
packet = sock.recv(size - len(data))
if not packet:
return None
data.extend(packet)
return bytes(data)
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((LISTEN_IP, LISTEN_PORT))
server.listen(1)
print(f"Waiting for sender on TCP port {LISTEN_PORT}...")
try:
connection, address = server.accept()
with connection:
connection.setsockopt(
socket.IPPROTO_TCP,
socket.TCP_NODELAY,
1,
)
print(f"Sender connected from {address[0]}:{address[1]}")
print("Press Q in the video window to stop.")
while True:
header = receive_exact(connection, HEADER_SIZE)
if header is None:
print("Sender disconnected.")
break
frame_size = struct.unpack("!I", header)[0]
if frame_size <= 0 or frame_size > MAX_FRAME_SIZE:
print(f"Invalid frame size: {frame_size}")
break
frame_data = receive_exact(connection, frame_size)
if frame_data is None:
print("Connection closed during frame reception.")
break
compressed_array = np.frombuffer(
frame_data,
dtype=np.uint8,
)
frame = cv2.imdecode(
compressed_array,
cv2.IMREAD_COLOR,
)
if frame is None:
print("Failed to decode frame.")
continue
cv2.imshow("Remote Screen - Press Q to exit", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
finally:
server.close()
cv2.destroyAllWindows()
print("Receiver stopped.")
if __name__ == "__main__":
main()
+116
View File
@@ -0,0 +1,116 @@
import signal
import socket
import struct
import time
import cv2
import numpy as np
from mss import mss
RECEIVER_IP = "172.16.11.81" # Your friend's computer IP
RECEIVER_PORT = 5000
FPS = 15
JPEG_QUALITY = 55
MONITOR_NUMBER = 1
running = True
def stop_stream(signum=None, frame=None):
global running
running = False
print("\nStopping screen stream safely...")
signal.signal(signal.SIGINT, stop_stream)
signal.signal(signal.SIGTERM, stop_stream)
def send_all(sock, data):
"""Send the complete byte sequence."""
view = memoryview(data)
while view and running:
bytes_sent = sock.send(view)
if bytes_sent == 0:
raise ConnectionError("TCP connection closed")
view = view[bytes_sent:]
def main():
print(f"Connecting to {RECEIVER_IP}:{RECEIVER_PORT}...")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
sock.connect((RECEIVER_IP, RECEIVER_PORT))
print("Connected.")
print("Press Ctrl+C once to stop.")
with mss() as sct:
monitor = sct.monitors[MONITOR_NUMBER]
frame_interval = 1.0 / FPS
next_frame_time = time.perf_counter()
while running:
screenshot = sct.grab(monitor)
frame = np.asarray(screenshot)
frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
# Reduce resolution to lower bandwidth.
frame = cv2.resize(
frame,
None,
fx=0.6,
fy=0.6,
interpolation=cv2.INTER_AREA,
)
success, encoded_frame = cv2.imencode(
".jpg",
frame,
[cv2.IMWRITE_JPEG_QUALITY, JPEG_QUALITY],
)
if not success:
continue
frame_data = encoded_frame.tobytes()
frame_size = len(frame_data)
# Network byte order, unsigned 4-byte integer.
header = struct.pack("!I", frame_size)
send_all(sock, header)
send_all(sock, frame_data)
print(
f"\rSent: {frame_size / 1024:.1f} KB",
end="",
flush=True,
)
next_frame_time += frame_interval
sleep_time = next_frame_time - time.perf_counter()
if sleep_time > 0:
time.sleep(sleep_time)
else:
next_frame_time = time.perf_counter()
print("\nScreen streaming stopped.")
if __name__ == "__main__":
try:
main()
except ConnectionRefusedError:
print("Connection refused. Start the receiver first.")
except (ConnectionError, BrokenPipeError) as error:
print(f"\nConnection lost: {error}")
+29
View File
@@ -0,0 +1,29 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
import sys
server_name = sys.argv[1]
port = int(sys.argv[2])
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
body = f"""
<html>
<body>
<h1>{server_name}</h1>
<p>Request path: {port}</p>
</body>
</html>
""".encode()
self.send_response(200)
self.send_header("Content-Type", "text/html")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, format, *args):
print(f"[{server_name}] {self.client_address[0]} - {format % args}")
HTTPServer(("127.0.0.1", port), Handler).serve_forever()
File diff suppressed because it is too large. Load diff