diff --git a/api/api/consumers.py b/api/api/consumers.py new file mode 100644 index 0000000..e4a046b --- /dev/null +++ b/api/api/consumers.py @@ -0,0 +1,22 @@ +# api/consumers.py +import json +from channels.generic.websocket import WebsocketConsumer + +class MediaConsumer(WebsocketConsumer): + def connect(self): + self.accept() + self.send(text_data=json.dumps({ + "message": "Connected to WebSocket server!" + })) + + def receive(self, text_data): + data = json.loads(text_data) + message = data.get("message", "") + + if message == "ping": + self.send(text_data=json.dumps({"response": "pong"})) + else: + self.send(text_data=json.dumps({"response": f"Received: {message}"})) + + def disconnect(self, close_code): + print("Disconnected from Websocket") \ No newline at end of file diff --git a/api/api/routing.py b/api/api/routing.py new file mode 100644 index 0000000..4819fc2 --- /dev/null +++ b/api/api/routing.py @@ -0,0 +1,7 @@ +# api/routing.py +from django.urls import path +from . import consumers + +websocket_urlpatterns= [ + path("ws/media/", consumers.MediaConsumer.as_asgi()), +] \ No newline at end of file diff --git a/api/backend/asgi.py b/api/backend/asgi.py index ed01e6a..6fa558d 100644 --- a/api/backend/asgi.py +++ b/api/backend/asgi.py @@ -8,9 +8,18 @@ https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ """ import os - from django.core.asgi import get_asgi_application +from channels.routing import ProtocolTypeRouter, URLRouter +from channels.auth import AuthMiddlewareStack +import api.routing os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') -application = get_asgi_application() +application = ProtocolTypeRouter({ + "http": get_asgi_application(), + "websocket": AuthMiddlewareStack( + URLRouter( + api.routing.websocket_urlpatterns + ) + ) +}) diff --git a/api/backend/settings.py b/api/backend/settings.py index 0ce5725..02acbd2 100644 --- a/api/backend/settings.py +++ b/api/backend/settings.py @@ -31,6 +31,8 @@ ALLOWED_HOSTS = ['*'] # Application definition INSTALLED_APPS = [ + 'daphne', + 'channels', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -72,7 +74,14 @@ TEMPLATES = [ ] WSGI_APPLICATION = 'backend.wsgi.application' +ASGI_APPLICATION = "backend.asgi.application" +# Redis setup for WebSocket communication +CHANNEL_LAYERS = { + "default": { + "BACKEND": "channels.layers.InMemoryChannelLayer" + } +} # Database # https://docs.djangoproject.com/en/5.1/ref/settings/#databases diff --git a/client/src/App.tsx b/client/src/App.tsx index 49f1eb3..d7a4f75 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -11,6 +11,7 @@ import { import { Home as HomeIcon } from '@mui/icons-material'; import theme from './theme/theme'; import { MediaProvider } from './contexts/MediaContext'; +import { WebSocketProvider } from './contexts/WebSocketContext'; // Import pages import LandingPage from './Pages/LandingPage'; import UploadPage from './Pages/UploadPage'; @@ -25,24 +26,26 @@ const App: React.FC = () => { - - - - FreqSplit - - - + + + + + FreqSplit + + + - - } /> - } /> - } /> - } /> - } /> - } /> - }/> - - + + } /> + } /> + } /> + } /> + } /> + } /> + }/> + + + ); diff --git a/client/src/contexts/WebSocketContext.tsx b/client/src/contexts/WebSocketContext.tsx new file mode 100644 index 0000000..7f6d1ac --- /dev/null +++ b/client/src/contexts/WebSocketContext.tsx @@ -0,0 +1,54 @@ +import React, { createContext, useContext, useEffect, useState } from "react"; + +const WEBSOCKET_URL = "ws://localhost:8000/ws/media/"; + +interface WebSocketContextType { + socket: WebSocket | null; + isConnected: boolean; +} + +const WebSocketContext = createContext({ + socket: null, + isConnected: false, +}); + +export const WebSocketProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const [socket, setSocket] = useState(null); + const [isConnected, setIsConnected] = useState(false); + + useEffect(() => { + const newSocket = new WebSocket(WEBSOCKET_URL); + + newSocket.onopen = () => { + console.log("Connected to WebSocket!"); + setIsConnected(true); + }; + + newSocket.onclose = () => { + console.warn("Disconnected from WebSocket"); + setIsConnected(false); + }; + + newSocket.onerror = (error) => { + console.error("WebSocket error:", error); + }; + + newSocket.onmessage = (event) => { + console.log("Message from server:", event.data); + }; + + setSocket(newSocket); + + return () => { + newSocket.close(); + }; + }, []); + + return ( + + {children} + + ); +}; + +export const useWebSocket = () => useContext(WebSocketContext); diff --git a/pyproject.toml b/pyproject.toml index 2a3cd4e..2b40929 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,133 +6,157 @@ build-backend = "setuptools.build_meta" name = "freqsplit" version = "0.1.0" dependencies = [ - "aiohappyeyeballs==2.4.6", - "aiohttp==3.11.13", - "aiosignal==1.3.2", - "amqp==5.3.1", - "antlr4-python3-runtime==4.9.3", - "appdirs==1.4.4", - "asgiref==3.8.1", - "asteroid==0.7.0", - "asteroid-filterbanks==0.4.0", - "attrs==25.1.0", - "audioread==3.0.1", - "billiard==4.2.1", - "cached-property==2.0.1", - "celery==5.4.0", - "certifi==2025.1.31", - "cffi==1.17.1", - "charset-normalizer==3.4.1", - "click==8.1.8", - "click-didyoumean==0.3.1", - "click-plugins==1.1.1", - "click-repl==0.3.0", - "cloudpickle==3.1.1", - "contourpy==1.3.1", - "cycler==0.12.1", - "decorator==5.2.1", - "DeepFilterLib==0.5.6", - "DeepFilterNet==0.5.6", - "demucs==4.0.1", - "Django==5.1.6", - "django-cors-headers==4.7.0", - "djangorestframework==3.15.2", - "dora_search==0.1.12", - "einops==0.8.1", - "filelock==3.17.0", - "fonttools==4.56.0", - "frozenlist==1.5.0", - "fsspec==2025.2.0", - "huggingface-hub==0.29.1", - "idna==3.10", - "iniconfig==2.0.0", - "Jinja2==3.1.5", - "joblib==1.4.2", - "julius==0.2.7", - "kiwisolver==1.4.8", - "kombu==5.4.2", - "lameenc==1.8.1", - "lazy_loader==0.4", - "librosa==0.10.2.post1", - "lightning-utilities==0.12.0", - "llvmlite==0.44.0", - "loguru==0.7.3", - "MarkupSafe==3.0.2", - "matplotlib==3.10.0", - "mir_eval==0.8.2", - "mpmath==1.3.0", - "msgpack==1.1.0", - "multidict==6.1.0", - "networkx==3.4.2", - "numba==0.61.0", - "numpy==1.26.4", - "nvidia-cublas-cu12==12.4.5.8", - "nvidia-cuda-cupti-cu12==12.4.127", - "nvidia-cuda-nvrtc-cu12==12.4.127", - "nvidia-cuda-runtime-cu12==12.4.127", - "nvidia-cudnn-cu12==9.1.0.70", - "nvidia-cufft-cu12==11.2.1.3", - "nvidia-curand-cu12==10.3.5.147", - "nvidia-cusolver-cu12==11.6.1.9", - "nvidia-cusparse-cu12==12.3.1.170", - "nvidia-cusparselt-cu12==0.6.2", - "nvidia-nccl-cu12==2.21.5", - "nvidia-nvjitlink-cu12==12.4.127", - "nvidia-nvtx-cu12==12.4.127", - "omegaconf==2.3.0", - "openunmix==1.3.0", - "packaging==23.2", - "pandas==2.2.3", - "panns-inference==0.1.1", - "pb-bss-eval==0.0.2", - "pesq==0.0.4", - "pillow==11.1.0", - "platformdirs==4.3.6", - "pluggy==1.5.0", - "pooch==1.8.2", - "prompt_toolkit==3.0.50", - "propcache==0.3.0", - "pycparser==2.22", - "pyparsing==3.2.1", - "pystoi==0.4.1", - "pytest==8.3.4", - "python-dateutil==2.9.0.post0", - "pytorch-lightning==2.5.0.post0", - "pytorch-ranger==0.1.1", - "pytz==2025.1", - "PyYAML==6.0.2", - "redis==5.2.1", - "regex==2024.11.6", - "requests==2.32.3", - "retrying==1.3.4", - "safetensors==0.5.3", - "scikit-learn==1.6.1", - "scipy==1.15.2", - "setuptools==75.8.1", - "six==1.17.0", - "soundfile==0.13.1", - "soxr==0.5.0.post1", - "sqlparse==0.5.3", - "submitit==1.5.2", - "sympy==1.13.1", - "threadpoolctl==3.5.0", - "tokenizers==0.21.0", - "torch==2.6.0", - "torch-optimizer==0.1.0", - "torch-stoi==0.2.3", - "torchaudio==2.6.0", - "torchlibrosa==0.1.0", - "torchmetrics==0.11.4", - "tqdm==4.67.1", - "transformers==4.49.0", - "treetable==0.2.5", - "triton==3.2.0", - "typing_extensions==4.12.2", - "tzdata==2025.1", - "urllib3==2.3.0", - "vine==5.1.0", - "wcwidth==0.2.13", - "yarl==1.18.3", + "aiohappyeyeballs" = "2.4.6", + "aiohttp" = "3.11.13", + "aiosignal" = "1.3.2", + "amqp" = "5.3.1", + "antlr4-python3-runtime" = "4.9.3", + "appdirs" = "1.4.4", + "asgiref" = "3.8.1", + "asteroid" = "0.7.0", + "asteroid-filterbanks" = "0.4.0", + "attrs" = "25.1.0", + "audioread" = "3.0.1", + "autobahn" = "24.4.2", + "Automat" = "24.8.1", + "billiard" = "4.2.1", + "cached-property" = "2.0.1", + "celery" = "5.4.0", + "certifi" = "2025.1.31", + "cffi" = "1.17.1", + "channels" = "4.2.0", + "charset-normalizer" = "3.4.1", + "click" = "8.1.8", + "click-didyoumean" = "0.3.1", + "click-plugins" = "1.1.1", + "click-repl" = "0.3.0", + "cloudpickle" = "3.1.1", + "colorama" = "0.4.6", + "constantly" = "23.10.4", + "contourpy" = "1.3.1", + "cors" = "1.0.1", + "cryptography" = "44.0.2", + "cycler" = "0.12.1", + "daphne" = "4.1.2", + "decorator" = "5.2.1", + "DeepFilterLib" = "0.5.6", + "DeepFilterNet" = "0.5.6", + "demucs" = "4.0.1", + "Django" = "5.1.6", + "django-cors-headers" = "4.7.0", + "djangorestframework" = "3.15.2", + "dora_search" = "0.1.12", + "einops" = "0.8.1", + "filelock" = "3.17.0", + "fonttools" = "4.56.0", + "frozenlist" = "1.5.0", + "fsspec" = "2025.2.0", + "future" = "1.0.0", + "gevent" = "24.11.1", + "greenlet" = "3.1.1", + "huggingface-hub" = "0.29.1", + "hyperlink" = "21.0.0", + "idna" = "3.10", + "incremental" = "24.7.2", + "iniconfig" = "2.0.0", + "Jinja2" = "3.1.5", + "joblib" = "1.4.2", + "julius" = "0.2.7", + "kiwisolver" = "1.4.8", + "kombu" = "5.4.2", + "lameenc" = "1.8.1", + "lazy_loader" = "0.4", + "librosa" = "0.10.2.post1", + "lightning-utilities" = "0.12.0", + "llvmlite" = "0.44.0", + "loguru" = "0.7.3", + "MarkupSafe" = "3.0.2", + "matplotlib" = "3.10.0", + "mir_eval" = "0.8.2", + "mpmath" = "1.3.0", + "msgpack" = "1.1.0", + "multidict" = "6.1.0", + "networkx" = "3.4.2", + "numba" = "0.61.0", + "numpy" = "1.26.4", + "nvidia-cublas-cu12" = "12.4.5.8", + "nvidia-cuda-cupti-cu12" = "12.4.127", + "nvidia-cuda-nvrtc-cu12" = "12.4.127", + "nvidia-cuda-runtime-cu12" = "12.4.127", + "nvidia-cudnn-cu12" = "9.1.0.70", + "nvidia-cufft-cu12" = "11.2.1.3", + "nvidia-curand-cu12" = "10.3.5.147", + "nvidia-cusolver-cu12" = "11.6.1.9", + "nvidia-cusparse-cu12" = "12.3.1.170", + "nvidia-cusparselt-cu12" = "0.6.2", + "nvidia-nccl-cu12" = "2.21.5", + "nvidia-nvjitlink-cu12" = "12.4.127", + "nvidia-nvtx-cu12" = "12.4.127", + "omegaconf" = "2.3.0", + "openunmix" = "1.3.0", + "packaging" = "23.2", + "pandas" = "2.2.3", + "panns-inference" = "0.1.1", + "pb-bss-eval" = "0.0.2", + "pesq" = "0.0.4", + "pillow" = "11.1.0", + "platformdirs" = "4.3.6", + "pluggy" = "1.5.0", + "pooch" = "1.8.2", + "prompt_toolkit" = "3.0.50", + "propcache" = "0.3.0", + "pyasn1" = "0.6.1", + "pyasn1_modules" = "0.4.1", + "pycparser" = "2.22", + "pyOpenSSL" = "25.0.0", + "pyparsing" = "3.2.1", + "PySocks" = "1.7.1", + "pystoi" = "0.4.1", + "pytest" = "8.3.4", + "python-dateutil" = "2.9.0.post0", + "pytorch-lightning" = "2.5.0.post0", + "pytorch-ranger" = "0.1.1", + "pytz" = "2025.1", + "PyYAML" = "6.0.2", + "redis" = "5.2.1", + "regex" = "2024.11.6", + "requests" = "2.32.3", + "requests-file" = "2.1.0", + "retrying" = "1.3.4", + "safetensors" = "0.5.3", + "scikit-learn" = "1.6.1", + "scipy" = "1.15.2", + "service-identity" = "24.2.0", + "setuptools" = "75.8.1", + "six" = "1.17.0", + "soundfile" = "0.13.1", + "soxr" = "0.5.0.post1", + "sqlparse" = "0.5.3", + "submitit" = "1.5.2", + "sympy" = "1.13.1", + "threadpoolctl" = "3.5.0", + "tldextract" = "5.1.3", + "tokenizers" = "0.21.0", + "torch" = "2.6.0", + "torch-optimizer" = "0.1.0", + "torch-stoi" = "0.2.3", + "torchaudio" = "2.6.0", + "torchlibrosa" = "0.1.0", + "torchmetrics" = "0.11.4", + "tqdm" = "4.67.1", + "transformers" = "4.49.0", + "treetable" = "0.2.5", + "triton" = "3.2.0", + "Twisted" = "24.11.0", + "txaio" = "23.1.1", + "typing_extensions" = "4.12.2", + "tzdata" = "2025.1", + "urllib3" = "2.3.0", + "vine" = "5.1.0", + "wcwidth" = "0.2.13", + "yarl" = "1.18.3", + "zope.event" = "5.0", + "zope.interface" = "7.2", ] [tool.setuptools] diff --git a/requirements.txt b/requirements.txt index cec5141..e33d7df 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,11 +9,14 @@ asteroid==0.7.0 asteroid-filterbanks==0.4.0 attrs==25.1.0 audioread==3.0.1 +autobahn==24.4.2 +Automat==24.8.1 billiard==4.2.1 cached-property==2.0.1 celery==5.4.0 certifi==2025.1.31 cffi==1.17.1 +channels==4.2.0 charset-normalizer==3.4.1 click==8.1.8 click-didyoumean==0.3.1 @@ -21,9 +24,12 @@ click-plugins==1.1.1 click-repl==0.3.0 cloudpickle==3.1.1 colorama==0.4.6 +constantly==23.10.4 contourpy==1.3.1 cors==1.0.1 +cryptography==44.0.2 cycler==0.12.1 +daphne==4.1.2 decorator==5.2.1 DeepFilterLib==0.5.6 DeepFilterNet==0.5.6 @@ -35,13 +41,16 @@ dora_search==0.1.12 einops==0.8.1 filelock==3.17.0 fonttools==4.56.0 +-e git+https://github.com/joelmathewthomas/freqsplit@c96b74c463f29fd5f50140701f92f92eb3109a2c#egg=freqsplit frozenlist==1.5.0 fsspec==2025.2.0 future==1.0.0 gevent==24.11.1 greenlet==3.1.1 huggingface-hub==0.29.1 +hyperlink==21.0.0 idna==3.10 +incremental==24.7.2 iniconfig==2.0.0 Jinja2==3.1.5 joblib==1.4.2 @@ -89,7 +98,10 @@ pluggy==1.5.0 pooch==1.8.2 prompt_toolkit==3.0.50 propcache==0.3.0 +pyasn1==0.6.1 +pyasn1_modules==0.4.1 pycparser==2.22 +pyOpenSSL==25.0.0 pyparsing==3.2.1 PySocks==1.7.1 pystoi==0.4.1 @@ -107,6 +119,7 @@ retrying==1.3.4 safetensors==0.5.3 scikit-learn==1.6.1 scipy==1.15.2 +service-identity==24.2.0 setuptools==75.8.1 six==1.17.0 soundfile==0.13.1 @@ -127,6 +140,8 @@ tqdm==4.67.1 transformers==4.49.0 treetable==0.2.5 triton==3.2.0 +Twisted==24.11.0 +txaio==23.1.1 typing_extensions==4.12.2 tzdata==2025.1 urllib3==2.3.0