Spaces:
Sleeping
Sleeping
| # app.py | |
| # --------------------------------------------------------- | |
| # THE SERVER β manages all API routes | |
| # | |
| # Routes: | |
| # GET / β serves frontend index.html | |
| # GET /health β health check | |
| # POST /transcribe β audio β text (any language) | |
| # POST /translate β text β translated text | |
| # GET /languages β returns all supported languages | |
| # --------------------------------------------------------- | |
| import os | |
| from flask import Flask, request, jsonify, send_from_directory | |
| from flask_cors import CORS | |
| from transcriber import transcribe_audio | |
| from translator import translate_text, get_supported_languages | |
| app = Flask(__name__) | |
| CORS(app) | |
| BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| UPLOAD_FOLDER = os.path.join(BASE_DIR, "uploads") | |
| FRONTEND_DIR = os.path.join(BASE_DIR, "frontend") | |
| os.makedirs(UPLOAD_FOLDER, exist_ok=True) | |
| # ββ Serve frontend βββββββββββββββββββββββββββββββββββββββββ | |
| def index(): | |
| return send_from_directory(FRONTEND_DIR, "index.html") | |
| def frontend_files(filename): | |
| return send_from_directory(FRONTEND_DIR, filename) | |
| # ββ Health check βββββββββββββββββββββββββββββββββββββββββββ | |
| def health(): | |
| return jsonify({"status": "ok", "app": "VoiceScript"}) | |
| # ββ Get supported languages ββββββββββββββββββββββββββββββββ | |
| # Frontend calls this on load to populate the language dropdown | |
| def languages(): | |
| return jsonify({ | |
| "success": True, | |
| "languages": get_supported_languages() | |
| }) | |
| # ββ Transcribe audio βββββββββββββββββββββββββββββββββββββββ | |
| # mode = "transcribe" β transcribe in original language | |
| # mode = "translate" β transcribe ANY language β English | |
| def transcribe(): | |
| if "audio" not in request.files: | |
| return jsonify({"success": False, "error": "No audio file received."}), 400 | |
| audio_file = request.files["audio"] | |
| if audio_file.filename == "": | |
| return jsonify({"success": False, "error": "Empty filename."}), 400 | |
| # Get mode from form data β default is "transcribe" | |
| # "translate_to_english" mode tells Whisper to output English | |
| # regardless of what language was spoken | |
| mode = request.form.get("mode", "transcribe") | |
| file_path = os.path.join(UPLOAD_FOLDER, "temp_audio") | |
| audio_file.save(file_path) | |
| result = transcribe_audio(file_path, mode=mode) | |
| if os.path.exists(file_path): | |
| os.remove(file_path) | |
| # Format segments into clean timestamped lines for frontend | |
| # Each segment: { start, end, text } | |
| # We convert seconds β [MM:SS] format here in backend | |
| if result.get("success") and result.get("segments"): | |
| timestamped = [] | |
| for seg in result["segments"]: | |
| start_sec = int(seg.get("start", 0)) | |
| end_sec = int(seg.get("end", 0)) | |
| text = seg.get("text", "").strip() | |
| if text: | |
| start_fmt = f"{start_sec // 60:02d}:{start_sec % 60:02d}" | |
| end_fmt = f"{end_sec // 60:02d}:{end_sec % 60:02d}" | |
| timestamped.append({ | |
| "start" : start_sec, | |
| "end" : end_sec, | |
| "start_fmt" : start_fmt, | |
| "end_fmt" : end_fmt, | |
| "text" : text | |
| }) | |
| result["timestamped"] = timestamped | |
| # Remove raw segments from response (too heavy) | |
| del result["segments"] | |
| return jsonify(result) | |
| # ββ Translate transcript βββββββββββββββββββββββββββββββββββ | |
| # Takes existing transcript text + target language code | |
| # Returns translated text | |
| def translate(): | |
| data = request.get_json() | |
| if not data: | |
| return jsonify({"success": False, "error": "No data received."}), 400 | |
| text = data.get("text", "").strip() | |
| target_lang = data.get("target_language", "") | |
| if not text: | |
| return jsonify({"success": False, "error": "No text to translate."}), 400 | |
| if not target_lang: | |
| return jsonify({"success": False, "error": "No target language specified."}), 400 | |
| result = translate_text(text, target_lang) | |
| return jsonify(result) | |
| # ββ Start server βββββββββββββββββββββββββββββββββββββββββββ | |
| if __name__ == "__main__": | |
| port = int(os.environ.get("PORT", 7860)) | |
| print(f"Starting VoiceScript Server on port {port}...") | |
| print(f"Visit: http://localhost:{port}") | |
| app.run(debug=False, host="0.0.0.0", port=port) | |