commit d1c12a08b0f3b0bcdab4711c6de25b4c388e21da Author: Your Name Date: Mon Dec 2 02:35:49 2024 +0500 init diff --git a/__pycache__/screen.cpython-313.pyc b/__pycache__/screen.cpython-313.pyc new file mode 100644 index 0000000..192e388 Binary files /dev/null and b/__pycache__/screen.cpython-313.pyc differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e28e6aa --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,7 @@ +services: + python: + volumes: + - './:/usr/src/app' + working_dir: /usr/src/app + build: . + command: python server.py diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000..b9bedfb --- /dev/null +++ b/dockerfile @@ -0,0 +1,10 @@ +FROM python:3 + +WORKDIR /usr/src/app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD [ "python", "./server.py" ] diff --git a/index.html b/index.html new file mode 100644 index 0000000..652f6fc --- /dev/null +++ b/index.html @@ -0,0 +1,173 @@ + + + + + + + Document + + + + + +
+
Loading
+
+ + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..448ed83 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +flask +websockets +pillow diff --git a/screen.py b/screen.py new file mode 100644 index 0000000..34c43fc --- /dev/null +++ b/screen.py @@ -0,0 +1,60 @@ +#Copyright (C) 2021 Qijun Gu +# +#This file is part of Screenshare. +# +#Screenshare is free software: you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +# +#Screenshare is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. +# +#You should have received a copy of the GNU General Public License +#along with Screenshare. If not, see . + +import threading, time, base64, sys + +ver = sys.version_info.major +if ver==2: + import StringIO as io +elif ver==3: + import io + +from PIL import ImageGrab as ig + +class Screen(): + def __init__(self): + self.FPS = 30 + self.screenbuf = "" + self.password = "" + if ver==2: + self.screenfile = io.StringIO() + elif ver==3: + self.screenfile = io.BytesIO() + threading.Thread(target=self.getframes).start() + + def __del__(self): + self.screenfile.close() + + def getframes(self): + while True: + im = ig.grab(bbox=(0, 0, 1920, 1080), include_layered_windows=False, all_screens=False, xdisplay=":0") + self.screenfile.seek(0) + self.screenfile.truncate(0) + im_converted = im.convert("RGB") + im_converted.save(self.screenfile, format="jpeg", quality=60, progressive=True) + self.screenbuf = base64.b64encode(self.screenfile.getvalue()) + time.sleep(1.0/self.FPS) + + def gen(self): + s = '' + if ver==2: + s = self.screenbuf + elif ver==3: + s = self.screenbuf.decode() + return s + +screenlive = Screen() diff --git a/server.py b/server.py new file mode 100644 index 0000000..0785dec --- /dev/null +++ b/server.py @@ -0,0 +1,95 @@ +from screen import screenlive +import json, argparse +from flask import Flask, json +import threading +from time import sleep +from websockets.sync.server import serve +import websockets +import array +import time + +api = Flask(__name__) +watchers_last_seen = {} +stream = False +debug = False + +def current_time(): + return str(int(time.time())) + +@api.route("/off", methods=["GET"]) +def streaOff(): + global stream + stream=False + return "True" + +@api.route("/on", methods=["GET"]) +def streamOn(): + global stream + stream=True + return "True" + +@api.route("/views", methods=["GET"]) +def views(): + global watchers_last_seen + return str(len(watchers_last_seen)) + + +def ws_server(websocket): + global stream, watchers_last_seen + if debug: print("WebSocket: Server Started.") + try: + while True: + req=websocket.recv() + if "%" in req: + args= req.split("%")[1] + args = dict(x.split("=") for x in args.split(";")) + req = req.split("%")[0] + if debug: print(req,"-----",args) + match (req): + case ("get_stream"): + if stream: + watchers_last_seen[args["uuid"]] = current_time() + websocket.send(f""+str(json.dumps([True, screenlive.gen()]))) + else: + websocket.send(f"null") + case (_): + websocket.send(f"null") + except websockets.exceptions.ConnectionClosedOK: + if debug: print("hungup") + except websockets.ConnectionClosedError: + if debug: print("Internal Server Error.") + +def run_ws_server(): + with serve(ws_server, "0.0.0.0", 7890) as server: + server.serve_forever() + +def timeout_task(): + while True: + for key,value in watchers_last_seen.items(): + if debug: print(key+"||||"+value) + if (int(current_time())-int(value)) > 5: + if debug: print(key+"is timed out") + watchers_last_seen.pop(key) + break + if debug: print("time -",current_time()) + if debug: print("watchers -",watchers_last_seen.keys()) + sleep(10) + +def run_flask_server(): + api.run() + +def main(): + t1 = threading.Thread(target=run_ws_server) + t2 = threading.Thread(target=run_flask_server) + t3 = threading.Thread(target=timeout_task) + + t1.start() + t2.start() + t3.start() + + t1.join() + t2.join() + t3.join() + +if __name__ == "__main__": + main()