feat: convert python backend to a pure WebSocket API server

This commit is contained in:
akukanara
2026-05-31 16:58:25 +07:00
Unverified
parent a77c6792c0
commit c8c6bc5770
3 changed files with 27 additions and 59 deletions
+24 -12
View File
@@ -110,9 +110,10 @@ To run character models on ONNX Runtime, you must place your standard PyTorch RV
--- ---
### 🖥️ 4. Build the Frontend (Optional) ### 🖥️ 4. Running the Frontend Client
*Note: Statically built files are already pre-compiled under `/frontend`. You only need to run this step if you have modified the Next.js workspace source files inside `/frontend-next`.* Since the Python backend operates purely as a WebSocket API service, you must run the Next.js frontend client separately.
#### Option A: Development Server (Quick & Recommended)
1. Navigate to the frontend directory: 1. Navigate to the frontend directory:
```bash ```bash
cd frontend-next cd frontend-next
@@ -121,34 +122,45 @@ To run character models on ONNX Runtime, you must place your standard PyTorch RV
```bash ```bash
npm install npm install
``` ```
3. Build and export static assets (this will automatically compile files and synchronize them to the `/frontend` directory via `copy-build.js`): 3. Spin up the dev server:
```bash ```bash
npm run dev
```
Open your browser and navigate to **`http://localhost:3000`**.
#### Option B: Compiled Static Production Web Server
1. Navigate to `frontend-next` and build the application:
```bash
cd frontend-next
npm install
npm run build npm run build
``` ```
*Note: This will compile static pages and copy them into the root `/frontend` folder.*
2. Serve the compiled output using a static file server of your choice:
- Using Node: `npx serve ../frontend -p 3000`
- Using Python: `python -m http.server 3000 --directory ../frontend`
Open **`http://localhost:3000`** in your browser.
--- ---
## 🏃 Running the Voice Changer ## 🏃 Running the Voice Changer
### Option A: Quick Launch (Windows) ### Step 1: Start the Python WebSocket Backend
Double-click the [start.bat](file:///M:/Users/ahmad/project/onnx-voice-changer/start.bat) file at the root. It automatically activates the Python virtual environment and fires up the server. Run the server using your terminal (defaults to port `8765`):
### Option B: Manual CLI Execution
Run the server using your terminal:
```bash ```bash
python server.py --host 127.0.0.1 --port 8765 --http_port 8000 --device cuda python server.py --host 127.0.0.1 --port 8765 --device cuda
``` ```
### ⚙️ Command-Line Arguments #### ⚙️ Command-Line Arguments
| Argument | Description | Default | | Argument | Description | Default |
|---|---|---| |---|---|---|
| `--host` | The address the WebSocket server binds to. | `127.0.0.1` | | `--host` | The address the WebSocket server binds to. | `127.0.0.1` |
| `--port` | WebSocket communication port. | `8765` | | `--port` | WebSocket communication port. | `8765` |
| `--http_port`| Port serving the static frontend Web UI. | `8000` |
| `--device` | The ONNX Runtime execution device (`cpu`, `cuda`, `dml`). | `cuda` | | `--device` | The ONNX Runtime execution device (`cpu`, `cuda`, `dml`). | `cuda` |
| `--model` | Target folder name in `weights/` to load directly upon startup. | `None` | | `--model` | Target folder name in `weights/` to load directly upon startup. | `None` |
Once started, the application will automatically launch your browser and direct you to the premium audio dashboard at `http://localhost:8000`. ### Step 2: Open the Frontend Dashboard
Make sure your frontend client is running (via `npm run dev` or a static server on `http://localhost:3000`), open it in your browser, and it will automatically connect to the WebSocket API backend.
--- ---
+1 -45
View File
@@ -20,9 +20,6 @@ import logging
import traceback import traceback
import argparse import argparse
import threading import threading
import webbrowser
from http.server import SimpleHTTPRequestHandler
import socketserver
import numpy as np import numpy as np
import torch import torch
import onnxruntime as ort import onnxruntime as ort
@@ -616,27 +613,7 @@ async def start_websocket_server(host, port):
async with websockets.serve(websocket_handler, host, port): async with websockets.serve(websocket_handler, host, port):
await asyncio.Future() await asyncio.Future()
# --- HTTP STATIC FILE SERVER FOR FRONTEND ---
def start_http_server(port, directory="frontend"):
class MyHandler(SimpleHTTPRequestHandler):
def __init__(self, *args, **kwargs):
# Force serve from directory relative to the project root
base_dir = os.path.dirname(os.path.abspath(__file__))
full_dir = os.path.join(base_dir, directory)
super().__init__(*args, directory=full_dir, **kwargs)
def log_message(self, format, *args):
# Suppress standard logging to prevent console pollution
pass
try:
# Create a TCPServer that allows address reuse
socketserver.TCPServer.allow_reuse_address = True
with socketserver.TCPServer(("", port), MyHandler) as httpd:
logger.info(f"Serving HTTP frontend on http://localhost:{port}")
httpd.serve_forever()
except Exception as e:
logger.error(f"Failed to start HTTP server: {e}")
# --- LOCAL AUDIO DEVICE STREAM MODE --- # --- LOCAL AUDIO DEVICE STREAM MODE ---
def run_local_device_mode(model_name, f0_up_key, f0_method, device, input_device, output_device, chunk_size): def run_local_device_mode(model_name, f0_up_key, f0_method, device, input_device, output_device, chunk_size):
@@ -709,7 +686,6 @@ if __name__ == "__main__":
parser.add_argument("--mode", type=str, default="websocket", choices=["websocket", "device"], help="Server running mode") parser.add_argument("--mode", type=str, default="websocket", choices=["websocket", "device"], help="Server running mode")
parser.add_argument("--host", type=str, default="127.0.0.1", help="WebSocket host") parser.add_argument("--host", type=str, default="127.0.0.1", help="WebSocket host")
parser.add_argument("--port", type=int, default=8765, help="WebSocket port") parser.add_argument("--port", type=int, default=8765, help="WebSocket port")
parser.add_argument("--http_port", type=int, default=8000, help="HTTP static server port for Web UI")
parser.add_argument("--model", type=str, default="", help="RVC Model folder name inside weights/") parser.add_argument("--model", type=str, default="", help="RVC Model folder name inside weights/")
parser.add_argument("--transpose", type=int, default=0, help="Pitch shift in semitones (transpose)") parser.add_argument("--transpose", type=int, default=0, help="Pitch shift in semitones (transpose)")
parser.add_argument("--f0_method", type=str, default="pm", choices=["pm", "harvest", "dio", "rmvpe"], help="Pitch extraction method") parser.add_argument("--f0_method", type=str, default="pm", choices=["pm", "harvest", "dio", "rmvpe"], help="Pitch extraction method")
@@ -731,27 +707,7 @@ if __name__ == "__main__":
sys.exit(1) sys.exit(1)
if args.mode == "websocket": if args.mode == "websocket":
# 1. Start HTTP Server in a background thread to serve the frontend! # Start the WebSocket server on the main event loop
http_thread = threading.Thread(
target=start_http_server,
args=(args.http_port, "frontend"),
daemon=True
)
http_thread.start()
# 2. Automatically open the Web UI in the default browser!
web_ui_url = f"http://127.0.0.1:{args.http_port}"
logger.info(f"Automatically launching Web UI at {web_ui_url} in browser...")
# We give it a tiny delay to ensure the HTTP server socket is open
def open_browser():
time.sleep(0.5)
webbrowser.open(web_ui_url)
browser_thread = threading.Thread(target=open_browser, daemon=True)
browser_thread.start()
# 3. Start the WebSocket server on the main event loop
try: try:
asyncio.run(start_websocket_server(args.host, args.port)) asyncio.run(start_websocket_server(args.host, args.port))
except KeyboardInterrupt: except KeyboardInterrupt:
+2 -2
View File
@@ -6,10 +6,10 @@ set VENV_PYTHON=..\rvc-tts-webui\venv\Scripts\python.exe
if exist "%VENV_PYTHON%" ( if exist "%VENV_PYTHON%" (
echo Menjalankan menggunakan virtual environment dari rvc-tts-webui... echo Menjalankan menggunakan virtual environment dari rvc-tts-webui...
"%VENV_PYTHON%" -u server.py --host 127.0.0.1 --port 8765 --http_port 8000 "%VENV_PYTHON%" -u server.py --host 127.0.0.1 --port 8765
) else ( ) else (
echo Virtual environment tidak ditemukan, mencoba menggunakan python sistem... echo Virtual environment tidak ditemukan, mencoba menggunakan python sistem...
python -u server.py --host 127.0.0.1 --port 8765 --http_port 8000 python -u server.py --host 127.0.0.1 --port 8765
) )
pause pause