CoolFace
Apppublic

Haseeb949/fluenta-backend

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
flaskapi.py181 linesDownload Raw Back to root
1# -*- coding: utf-8 -*-2"""FlaskAPI.ipynb3 4Automatically generated by Colab.5 6Original file is located at7    https://colab.research.google.com/drive/1uihvsfycjhZr7FmzC4x3yC8hZX0ChuKV8"""9 10import os11import numpy as np12import librosa13!pip install noisereduce==2.0.114import noisereduce as nr15import joblib16from flask import Flask, request, jsonify17from datetime import datetime18!pip install flask pyngrok librosa noisereduce scikit-learn joblib19!python app.py20!apt install ffmpeg21!pip install pydub22from pydub import AudioSegment23 24from google.colab import files25uploaded = files.upload()26 27# Load model28MODEL_PATH = "/content/drive/MyDrive/Fluenta_Models/stutter_model_final.pkl"29SCALER_PATH = "/content/drive/MyDrive/Fluenta_Models/scaler_final.pkl"30FEATURE_COUNT_PATH = "/content/drive/MyDrive/Fluenta_Models/feature_count.pkl"31 32model = joblib.load(MODEL_PATH)33scaler = joblib.load(SCALER_PATH)34feature_count = joblib.load(FEATURE_COUNT_PATH)35 36# Flask App37app = Flask(__name__)38predictions_log = []39def preprocess_audio(audio, sr):40    audio, _ = librosa.effects.trim(audio, top_db=20)41    audio = librosa.util.normalize(audio)42    try:43        audio = nr.reduce_noise(y=audio, sr=sr, prop_decrease=0.8)44    except:45        pass46    if sr != 16000:47        audio = librosa.resample(audio, orig_sr=sr, target_sr=16000)48        sr = 1600049    min_length = int(0.5 * sr)50    if len(audio) < min_length:51        audio = np.pad(audio, (0, min_length - len(audio)), mode='constant')52    return audio, sr53 54# Feature Extraction55def extract_features(file_path):56    try:57        audio, sr = librosa.load(file_path, sr=None)58        audio, sr = preprocess_audio(audio, sr)59 60        features = []61        mfccs = librosa.feature.mfcc(y=audio, sr=sr, n_mfcc=20)62        features.extend(np.mean(mfccs.T, axis=0))63        features.extend(np.std(mfccs.T, axis=0))64 65        spectral_centroids = librosa.feature.spectral_centroid(y=audio, sr=sr)[0]66        spectral_rolloff = librosa.feature.spectral_rolloff(y=audio, sr=sr)[0]67        zcr = librosa.feature.zero_crossing_rate(audio)[0]68        chroma = librosa.feature.chroma_stft(y=audio, sr=sr)69        rms = librosa.feature.rms(y=audio)[0]70 71        features += [np.mean(spectral_centroids), np.std(spectral_centroids),72                     np.mean(spectral_rolloff), np.std(spectral_rolloff),73                     np.mean(zcr), np.std(zcr),74                     *np.mean(chroma.T, axis=0),75                     np.mean(rms), np.std(rms)]76 77        return np.array(features)78    except Exception as e:79        print(f"Feature extraction error: {e}")80        return None81 82# Prediction Endpoint83@app.route('/predict', methods=['POST'])84def predict():85    if 'file' not in request.files:86        return jsonify({'error': 'No audio file uploaded'}), 40087 88    file = request.files['file']89    filename = file.filename90    filepath = f"/tmp/{filename}"91    file.save(filepath)92 93    #Convert any non-WAV file to WAV automatically94    if not filename.lower().endswith(".wav"):95        wav_path = f"/tmp/converted.wav"96        try:97            sound = AudioSegment.from_file(filepath)98            sound.export(wav_path, format="wav")99            os.remove(filepath)100            filepath = wav_path101            print(f"Converted {filename} to WAV format.")102        except Exception as e:103            return jsonify({"error": f"File conversion failed: {e}"}), 500104 105    # Extract features106    features = extract_features(filepath)107    os.remove(filepath)108 109    if features is None:110        return jsonify({'error': 'Feature extraction failed'}), 500111 112    if len(features) != feature_count:113        return jsonify({'error': f'Feature count mismatch. Expected {feature_count}, got {len(features)}'}), 500114 115    features_scaled = scaler.transform([features])116    prediction = model.predict(features_scaled)[0]117    proba = model.predict_proba(features_scaled)[0] if hasattr(model, 'predict_proba') else None118 119    result_label = "Stutter" if prediction == 1 else "Non Stutter"120    confidence = round(float(proba[prediction]) * 100, 2) if proba is not None else None121    fluency_score = round(100 - confidence, 2) if result_label == "Stutter" else confidence122 123    feedback = (124        "Severe stuttering detected. Fluency score: 0%. Try to relax and slow down."125        if fluency_score <= 25 else126        "Moderate stuttering detected. Keep practicing!"127        if fluency_score <= 75 else128        "Great job! No stutter detected. Fluency score: 100%."129    )130 131    result = {132        "prediction": result_label,133        "confidence": confidence,134        "fluency_score": fluency_score,135        "feedback": feedback136    }137 138    # Track prediction139    predictions_log.append({140        "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),141        "filename": filename,142        "prediction": result_label,143        "confidence": confidence144    })145 146    return jsonify(result)147 148# Stats Endpoint149@app.route('/stats')150def stats():151    if not predictions_log:152        return jsonify({"message": "No predictions yet"})153 154    total = len(predictions_log)155    stutter_count = sum(1 for p in predictions_log if p["prediction"] == "Stutter")156 157    return jsonify({158        "total_predictions": total,159        "stutter_predictions": stutter_count,160        "fluent_predictions": total - stutter_count,161        "stutter_percentage": round(stutter_count / total * 100, 2)162    })163 164!ngrok config add-authtoken 33HVMsJ3w9V3ztrSLmbVKi0ZdMS_5orXJd2WC1qHP8A21YMwH165 166# Run with ngrok167from pyngrok import ngrok168 169@app.route('/')170def home():171    return jsonify({"message": "Enhanced Stuttering Detection API is running!"})172 173if __name__ == '__main__':174    public_url = ngrok.connect(5000)175    print(f"\n๐Ÿš€ Public URL: {public_url}\n")176    app.run(port=5000)177 178!killall ngrok179!pkill -f ngrok180ngrok.kill()181!rm -rf /root/.ngrok2/ngrok.yml