commit c398a816ae1401575084d13ba0beae566b2f9cd8 Author: suvodip ghosh Date: Sat May 31 10:15:46 2025 +0000 init diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..748b45e --- /dev/null +++ b/Caddyfile @@ -0,0 +1,9 @@ +{ + admin :2019 + auto_https off +} + +http:// { + reverse_profile /socket.io/* localhost:8000 + reverse_proxy /* localhost:8000 +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..acfa937 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,35 @@ +FROM python:3.9-slim as base + +# Install dependencies +RUN apt-get update && apt-get install -y \ + python3-pip \ + ffmpeg \ + wget \ + && rm -rf /var/lib/apt/lists/* + +# Install Python requirements +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Download Vosk model +RUN wget https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip && \ + unzip vosk-model-small-en-us-0.15.zip && \ + mv vosk-model-small-en-us-0.15 model && \ + rm vosk-model-small-en-us-0.15.zip + +# Copy application code +COPY app.py . +COPY Caddyfile . + +FROM base as production +# Install gunicorn and eventlet +RUN pip install gunicorn eventlet + +# Expose ports (8000 for app, 2019 for Caddy admin) +EXPOSE 8000 2019 + +CMD ["caddy", "run", "--config", "/app/Caddyfile"] + +FROM base as development +# For development with auto-reload +CMD ["python", "app.py"] \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..5cd1495 --- /dev/null +++ b/app.py @@ -0,0 +1,37 @@ +import eventlet +eventlet.monkey_patch() + +from flask import Flask, send_from_directory +from flask_socketio import SocketIO +from vosk import Model, KaldiRecognizer +import json +import os +from dotenv import load_dotenv + +load_dotenv() + +app = Flask(__name__, static_folder='static') +socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet') + +# Load the model +model = Model("model") + +@app.route('/') +def serve_index(): + return send_from_directory('static', 'index.html') + +@socketio.on('audio_stream') +def handle_audio_stream(audio_data): + recognizer = KaldiRecognizer(model, 16000) + recognizer.SetWords(True) + + if recognizer.AcceptWaveform(audio_data): + result = json.loads(recognizer.Result()) + socketio.emit('transcription', result.get('text', '')) + else: + partial = json.loads(recognizer.PartialResult()) + socketio.emit('partial_transcription', partial.get('partial', '')) + +if __name__ == '__main__': + os.makedirs('static', exist_ok=True) + socketio.run(app, host='0.0.0.0', port=8000) \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0f2ced3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + app: + build: + context: . + target: production + ports: + - "80:80" + - "443:443" + - "2019:2019" + volumes: + - ./static:/app/static + - ./Caddyfile:/app/Caddyfile + environment: + - FLASK_ENV=production + restart: unless-stopped \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d0205e4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +vosk>=0.3.44 +flask>=2.0.0 +flask-socketio>=5.0.0 +eventlet>=0.33.0 +python-dotenv>=0.19.0 +caddy>=2.4.6 \ No newline at end of file diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..d7bce07 --- /dev/null +++ b/static/index.html @@ -0,0 +1,103 @@ + + + + Vosk Audio Streaming + + + + +

Real-time Speech Recognition

+ + +
+ + + + \ No newline at end of file