diff --git a/whisperlivekit/__init__.py b/whisperlivekit/__init__.py
index 4547c3d..50fb50c 100644
--- a/whisperlivekit/__init__.py
+++ b/whisperlivekit/__init__.py
@@ -1,12 +1,13 @@
from .audio_processor import AudioProcessor
from .core import TranscriptionEngine
from .parse_args import parse_args
-from .web.web_interface import get_web_interface_html
+from .web.web_interface import get_web_interface_html, get_inline_ui_html
__all__ = [
"TranscriptionEngine",
"AudioProcessor",
"parse_args",
"get_web_interface_html",
+ "get_inline_ui_html",
"download_simulstreaming_backend",
]
diff --git a/whisperlivekit/basic_server.py b/whisperlivekit/basic_server.py
index ba6181e..b66eefd 100644
--- a/whisperlivekit/basic_server.py
+++ b/whisperlivekit/basic_server.py
@@ -2,7 +2,7 @@ from contextlib import asynccontextmanager
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from fastapi.middleware.cors import CORSMiddleware
-from whisperlivekit import TranscriptionEngine, AudioProcessor, get_web_interface_html, parse_args
+from whisperlivekit import TranscriptionEngine, AudioProcessor, get_inline_ui_html, parse_args
import asyncio
import logging
from starlette.staticfiles import StaticFiles
@@ -38,7 +38,7 @@ app.mount("/web", StaticFiles(directory=str(web_dir)), name="web")
@app.get("/")
async def get():
- return HTMLResponse(get_web_interface_html())
+ return HTMLResponse(get_inline_ui_html())
async def handle_websocket_results(websocket, results_generator):
diff --git a/whisperlivekit/web/web_interface.py b/whisperlivekit/web/web_interface.py
index 0b0886e..44cfd4f 100644
--- a/whisperlivekit/web/web_interface.py
+++ b/whisperlivekit/web/web_interface.py
@@ -1,5 +1,6 @@
import logging
import importlib.resources as resources
+import base64
logger = logging.getLogger(__name__)
@@ -12,6 +13,67 @@ def get_web_interface_html():
logger.error(f"Error loading web interface HTML: {e}")
return "
Error loading interface
"
+def get_inline_ui_html():
+ """Returns the complete web interface HTML with all assets embedded in a single call."""
+ try:
+ # Load HTML template
+ with resources.files('whisperlivekit.web').joinpath('live_transcription.html').open('r', encoding='utf-8') as f:
+ html_content = f.read()
+
+ # Load CSS and embed it
+ with resources.files('whisperlivekit.web').joinpath('live_transcription.css').open('r', encoding='utf-8') as f:
+ css_content = f.read()
+
+ # Load JS and embed it
+ with resources.files('whisperlivekit.web').joinpath('live_transcription.js').open('r', encoding='utf-8') as f:
+ js_content = f.read()
+
+ # Load SVG files and convert to data URIs
+ with resources.files('whisperlivekit.web').joinpath('src', 'system_mode.svg').open('r', encoding='utf-8') as f:
+ system_svg = f.read()
+ system_data_uri = f"data:image/svg+xml;base64,{base64.b64encode(system_svg.encode('utf-8')).decode('utf-8')}"
+
+ with resources.files('whisperlivekit.web').joinpath('src', 'light_mode.svg').open('r', encoding='utf-8') as f:
+ light_svg = f.read()
+ light_data_uri = f"data:image/svg+xml;base64,{base64.b64encode(light_svg.encode('utf-8')).decode('utf-8')}"
+
+ with resources.files('whisperlivekit.web').joinpath('src', 'dark_mode.svg').open('r', encoding='utf-8') as f:
+ dark_svg = f.read()
+ dark_data_uri = f"data:image/svg+xml;base64,{base64.b64encode(dark_svg.encode('utf-8')).decode('utf-8')}"
+
+ # Replace external references with embedded content
+ html_content = html_content.replace(
+ '',
+ f''
+ )
+
+ html_content = html_content.replace(
+ '',
+ f''
+ )
+
+ # Replace SVG references with data URIs
+ html_content = html_content.replace(
+ '
',
+ f'
'
+ )
+
+ html_content = html_content.replace(
+ '
',
+ f'
'
+ )
+
+ html_content = html_content.replace(
+ '
',
+ f'
'
+ )
+
+ return html_content
+
+ except Exception as e:
+ logger.error(f"Error creating embedded web interface: {e}")
+ return "Error loading embedded interface
"
+
if __name__ == '__main__':
@@ -28,6 +90,6 @@ if __name__ == '__main__':
@app.get("/")
async def get():
- return HTMLResponse(get_web_interface_html())
+ return HTMLResponse(get_inline_ui_html())
- uvicorn.run(app=app)
\ No newline at end of file
+ uvicorn.run(app=app)