diff --git a/software/main.py b/software/main.py index 9dccb81..4642fa3 100644 --- a/software/main.py +++ b/software/main.py @@ -10,9 +10,11 @@ import os import importlib from source.server.server import start_server import subprocess +import webview import socket import json import segno +from livekit import api import time from dotenv import load_dotenv import signal @@ -158,7 +160,7 @@ def run( livekit_thread.start() threads.append(livekit_thread) - livekit_url = f"ws://{server_host}:{server_port}" + local_livekit_url = f"ws://{server_host}:{server_port}" if expose: @@ -179,14 +181,6 @@ def run( if server == "livekit": print("Livekit server will run at:", url) - ### DISPLAY QR CODE - - if qr: - time.sleep(7) - content = json.dumps({"livekit_server": url}) - qr_code = segno.make(content) - qr_code.terminal(compact=True) - ### CLIENT @@ -233,13 +227,31 @@ def run( else: raise Exception(f"Server at {url} failed to respond after 10 attempts") - # Start the livekit worker + ### DISPLAY QR CODE + if qr: + content = json.dumps({"livekit_server": url}) + qr_code = segno.make(content) + qr_code.terminal(compact=True) + + ### START LIVEKIT WORKER if server == "livekit": time.sleep(7) # These are needed to communicate with the worker's entrypoint os.environ['INTERPRETER_SERVER_HOST'] = light_server_host os.environ['INTERPRETER_SERVER_PORT'] = str(light_server_port) - worker_main(livekit_url) + + token = str(api.AccessToken('devkey', 'secret') \ + .with_identity("identity") \ + .with_name("my name") \ + .with_grants(api.VideoGrants( + room_join=True, + room="my-room", + )).to_jwt()) + + meet_url = f'https://meet.livekit.io/custom?liveKitUrl={url.replace("http", "ws")}&token={token}\n\n' + print(meet_url) + + worker_main(local_livekit_url) # Wait for all threads to complete for thread in threads: diff --git a/software/poetry.lock b/software/poetry.lock index 3a5d26a..e02ab52 100644 --- a/software/poetry.lock +++ b/software/poetry.lock @@ -496,6 +496,17 @@ files = [ [package.dependencies] numpy = {version = ">=1.19.0", markers = "python_version >= \"3.9\""} +[[package]] +name = "bottle" +version = "0.12.25" +description = "Fast and simple WSGI-framework for small web-applications." +optional = false +python-versions = "*" +files = [ + {file = "bottle-0.12.25-py3-none-any.whl", hash = "sha256:d6f15f9d422670b7c073d63bd8d287b135388da187a0f3e3c19293626ce034ea"}, + {file = "bottle-0.12.25.tar.gz", hash = "sha256:e1a9c94970ae6d710b3fb4526294dfeb86f2cb4a81eff3a4b98dc40fb0e5e021"}, +] + [[package]] name = "cachetools" version = "5.5.0" @@ -752,6 +763,20 @@ azure = ["azure-storage-blob (>=12)", "azure-storage-file-datalake (>=12)"] gs = ["google-cloud-storage"] s3 = ["boto3 (>=1.34.0)"] +[[package]] +name = "clr-loader" +version = "0.2.6" +description = "Generic pure Python loader for .NET runtimes" +optional = false +python-versions = ">=3.7" +files = [ + {file = "clr_loader-0.2.6-py3-none-any.whl", hash = "sha256:79bbfee4bf6ac2f4836d89af2c39e0c32dce5d0c062596185aef380f317507a6"}, + {file = "clr_loader-0.2.6.tar.gz", hash = "sha256:019348ae6b6a83c7a406d14537c277cecf7a3a53b263ec342c81ded5845a67ee"}, +] + +[package.dependencies] +cffi = ">=1.13" + [[package]] name = "colorama" version = "0.4.6" @@ -4493,6 +4518,16 @@ files = [ {file = "protobuf-4.25.4.tar.gz", hash = "sha256:0dc4a62cc4052a036ee2204d26fe4d835c62827c855c8a03f29fe6da146b380d"}, ] +[[package]] +name = "proxy-tools" +version = "0.1.0" +description = "Proxy Implementation" +optional = false +python-versions = "*" +files = [ + {file = "proxy_tools-0.1.0.tar.gz", hash = "sha256:ccb3751f529c047e2d8a58440d86b205303cf0fe8146f784d1cbcd94f0a28010"}, +] + [[package]] name = "psutil" version = "5.9.8" @@ -8043,6 +8078,20 @@ files = [ {file = "python3-xlib-0.15.tar.gz", hash = "sha256:dc4245f3ae4aa5949c1d112ee4723901ade37a96721ba9645f2bfa56e5b383f8"}, ] +[[package]] +name = "pythonnet" +version = "3.0.3" +description = ".NET and Mono integration for Python" +optional = false +python-versions = "<3.13,>=3.7" +files = [ + {file = "pythonnet-3.0.3-py3-none-any.whl", hash = "sha256:62486f860c7955b7dcf470e085e4d2b599512224ca24193f716e857b496c530f"}, + {file = "pythonnet-3.0.3.tar.gz", hash = "sha256:8d4b2e97158a023875f8647458a58f38817f4fe39af60abdd6b0d8adf1d77e75"}, +] + +[package.dependencies] +clr-loader = ">=0.2.6,<0.3.0" + [[package]] name = "pyttsx3" version = "2.90" @@ -8080,6 +8129,37 @@ files = [ {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] +[[package]] +name = "pywebview" +version = "5.2" +description = "Build GUI for your Python program with JavaScript, HTML, and CSS" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pywebview-5.2-py3-none-any.whl", hash = "sha256:07acceb74bfeed2b5bf19b9535f23ed68330ec6488ae63aea4d35290941cad7f"}, + {file = "pywebview-5.2.tar.gz", hash = "sha256:634c6e4547ef3f4de2a35cdaed59464b60fb61247f3f6017d6de4ddc1a2dadc2"}, +] + +[package.dependencies] +bottle = "*" +proxy-tools = "*" +pyobjc-core = {version = "*", markers = "sys_platform == \"darwin\""} +pyobjc-framework-Cocoa = {version = "*", markers = "sys_platform == \"darwin\""} +pyobjc-framework-Quartz = {version = "*", markers = "sys_platform == \"darwin\""} +pyobjc-framework-security = {version = "*", markers = "sys_platform == \"darwin\""} +pyobjc-framework-WebKit = {version = "*", markers = "sys_platform == \"darwin\""} +pythonnet = {version = "*", markers = "sys_platform == \"win32\""} +QtPy = {version = "*", markers = "sys_platform == \"openbsd6\""} +typing-extensions = "*" + +[package.extras] +android = ["jnius", "kivy"] +cef = ["cefpython3"] +gtk = ["PyGObject", "PyGObject-stubs"] +pyside2 = ["PySide2", "QtPy"] +pyside6 = ["PySide6", "QtPy"] +qt = ["PyQt5", "QtPy", "pyqtwebengine"] + [[package]] name = "pywin32" version = "306" @@ -8327,6 +8407,23 @@ files = [ [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} +[[package]] +name = "qtpy" +version = "2.4.1" +description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)." +optional = false +python-versions = ">=3.7" +files = [ + {file = "QtPy-2.4.1-py3-none-any.whl", hash = "sha256:1c1d8c4fa2c884ae742b069151b0abe15b3f70491f3972698c683b8e38de839b"}, + {file = "QtPy-2.4.1.tar.gz", hash = "sha256:a5a15ffd519550a1361bdc56ffc07fda56a6af7292f17c7b395d4083af632987"}, +] + +[package.dependencies] +packaging = "*" + +[package.extras] +test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] + [[package]] name = "readchar" version = "4.2.0" @@ -10833,4 +10930,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "cb8278cca1e4370e315e3dad55494e3fb9ba5e097a500a9d4d41b7c932bf846b" +content-hash = "c93b6b4a2af7c4bfb4c55d2042e0ba6f2efad31f0c4e1ac4883322cd9b2a2eac" diff --git a/software/pyproject.toml b/software/pyproject.toml index 83ebef5..171730a 100644 --- a/software/pyproject.toml +++ b/software/pyproject.toml @@ -25,6 +25,7 @@ realtimetts = {extras = ["all"], version = "^0.4.5"} realtimestt = "^0.2.41" pynput = "^1.7.7" yaspin = "^3.0.2" +pywebview = "^5.2" [build-system] requires = ["poetry-core"]