|
from fastapi import FastAPI |
|
from asgiref.wsgi import WsgiToAsgi |
|
from flask import Flask, render_template, request, redirect, url_for |
|
import os |
|
import librosa |
|
import numpy as np |
|
import tensorflow as tf |
|
from sklearn.preprocessing import StandardScaler |
|
import pickle |
|
import subprocess |
|
import threading |
|
from fastapi.middleware.wsgi import WSGIMiddleware |
|
|
|
flask_app = Flask(__name__) |
|
|
|
|
|
UPLOAD_FOLDER = 'static/uploads' |
|
flask_app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER |
|
|
|
|
|
model = tf.keras.models.load_model('model_code1.keras') |
|
with open('scaler.pkl', 'rb') as f: |
|
scaler = pickle.load(f) |
|
|
|
|
|
genres = ['blues', 'classical', 'country', 'disco', 'hiphop', 'jazz', 'metal', 'pop', 'reggae', 'rock'] |
|
|
|
|
|
def delete_file_after_delay(file_path, delay=3600): |
|
def delete_file(): |
|
try: |
|
if os.path.exists(file_path): |
|
os.remove(file_path) |
|
print(f"File {file_path} berhasil dihapus setelah {delay} detik.") |
|
except Exception as e: |
|
print(f"Gagal menghapus file {file_path}: {e}") |
|
|
|
|
|
threading.Timer(delay, delete_file).start() |
|
|
|
|
|
def convert_mp3_to_wav(mp3_path): |
|
wav_path = mp3_path.replace('.mp3', '.wav') |
|
try: |
|
|
|
subprocess.run(['ffmpeg', '-i', mp3_path, wav_path], check=True) |
|
|
|
os.remove(mp3_path) |
|
return wav_path |
|
except subprocess.CalledProcessError as e: |
|
print(f"Error converting MP3 to WAV: {e}") |
|
return None |
|
except OSError as e: |
|
print(f"Error deleting MP3 file: {e}") |
|
return None |
|
|
|
|
|
def extract_features(file_path): |
|
try: |
|
y, sr = librosa.load(file_path, duration=30, sr=22050) |
|
|
|
|
|
mfccs = np.mean(librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13).T, axis=0) |
|
chroma = np.mean(librosa.feature.chroma_stft(y=y, sr=sr).T, axis=0) |
|
spectral_contrast = np.mean(librosa.feature.spectral_contrast(y=y, sr=sr).T, axis=0) |
|
zero_crossings = np.mean(librosa.feature.zero_crossing_rate(y).T, axis=0) |
|
tempo, _ = librosa.beat.beat_track(y=y, sr=sr) |
|
|
|
|
|
features = np.hstack([mfccs, chroma, spectral_contrast, zero_crossings, tempo]) |
|
return features |
|
except Exception as e: |
|
print(f"Error extracting features: {e}") |
|
return None |
|
|
|
|
|
@flask_app.route('/', methods=['GET', 'POST']) |
|
def index(): |
|
if request.method == 'POST': |
|
|
|
if 'file' not in request.files: |
|
return redirect(request.url) |
|
file = request.files['file'] |
|
if file.filename == '': |
|
return redirect(request.url) |
|
|
|
|
|
file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename) |
|
file.save(file_path) |
|
|
|
|
|
if file.filename.lower().endswith('.mp3'): |
|
|
|
file_path_wav = convert_mp3_to_wav(file_path) |
|
if file_path_wav is None: |
|
return "Konversi MP3 ke WAV gagal. Pastikan file yang diunggah valid." |
|
file_path = file_path_wav |
|
|
|
|
|
features = extract_features(file_path) |
|
if features is None: |
|
return "Ekstraksi fitur gagal. Coba unggah file lain." |
|
|
|
|
|
features_scaled = scaler.transform([features]) |
|
|
|
|
|
prediction = model.predict(features_scaled) |
|
predicted_genre = genres[np.argmax(prediction)] |
|
|
|
|
|
delete_file_after_delay(file_path, delay=30) |
|
|
|
|
|
return render_template('index.html', file_path=file_path, prediction=predicted_genre) |
|
|
|
return render_template('index.html') |
|
|
|
|
|
|
|
app = FastAPI() |
|
|
|
|
|
app.mount("/", WSGIMiddleware(flask_app)) |