Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
from streamlit.components.v1 import html
|
| 3 |
+
import base64
|
| 4 |
+
import os
|
| 5 |
+
|
| 6 |
+
# Streamlit UI
|
| 7 |
+
st.title("Project Shazam - Audio Input")
|
| 8 |
+
|
| 9 |
+
# Option to upload or record audio
|
| 10 |
+
option = st.radio("Choose an option:", ("Upload Audio File", "Record Audio"))
|
| 11 |
+
|
| 12 |
+
# Function to save audio data to a file
|
| 13 |
+
def save_audio(audio_data, filename="/tmp/input_audio"):
|
| 14 |
+
audio_bytes = base64.b64decode(audio_data)
|
| 15 |
+
with open(filename, "wb") as f:
|
| 16 |
+
f.write(audio_bytes)
|
| 17 |
+
return filename
|
| 18 |
+
|
| 19 |
+
# Upload Audio File
|
| 20 |
+
if option == "Upload Audio File":
|
| 21 |
+
uploaded_file = st.file_uploader("Upload any audio file (up to 2 minutes recommended)", type=None)
|
| 22 |
+
if uploaded_file is not None:
|
| 23 |
+
# Determine file extension and MIME type
|
| 24 |
+
file_extension = uploaded_file.name.split('.')[-1].lower()
|
| 25 |
+
mime_types = {
|
| 26 |
+
"mp3": "audio/mpeg",
|
| 27 |
+
"wav": "audio/wav",
|
| 28 |
+
"ogg": "audio/ogg",
|
| 29 |
+
"m4a": "audio/mp4",
|
| 30 |
+
"flac": "audio/flac"
|
| 31 |
+
}
|
| 32 |
+
mime_type = mime_types.get(file_extension, "audio/mpeg") # Default to MP3 if unknown
|
| 33 |
+
filename = f"/tmp/uploaded_audio.{file_extension}"
|
| 34 |
+
|
| 35 |
+
# Save uploaded file
|
| 36 |
+
with open(filename, "wb") as f:
|
| 37 |
+
f.write(uploaded_file.read())
|
| 38 |
+
st.success(f"Audio uploaded and saved as '{os.path.basename(filename)}'!")
|
| 39 |
+
|
| 40 |
+
# HTML5 audio player with controls
|
| 41 |
+
audio_player_html = f"""
|
| 42 |
+
<audio controls>
|
| 43 |
+
<source src="data:{mime_type};base64,{base64.b64encode(open(filename, 'rb').read()).decode()}" type="{mime_type}">
|
| 44 |
+
Your browser does not support the audio element.
|
| 45 |
+
</audio>
|
| 46 |
+
"""
|
| 47 |
+
st.markdown("### Listen to Uploaded Audio:")
|
| 48 |
+
html(audio_player_html)
|
| 49 |
+
|
| 50 |
+
# Record Audio
|
| 51 |
+
elif option == "Record Audio":
|
| 52 |
+
st.write("Record audio (up to 2 minutes):")
|
| 53 |
+
|
| 54 |
+
# HTML and JavaScript for recording with live timer
|
| 55 |
+
audio_recorder_html = """
|
| 56 |
+
<script>
|
| 57 |
+
let mediaRecorder;
|
| 58 |
+
let audioChunks = [];
|
| 59 |
+
let startTime;
|
| 60 |
+
let timerInterval;
|
| 61 |
+
|
| 62 |
+
function startRecording() {
|
| 63 |
+
navigator.mediaDevices.getUserMedia({ audio: true })
|
| 64 |
+
.then(stream => {
|
| 65 |
+
mediaRecorder = new MediaRecorder(stream);
|
| 66 |
+
mediaRecorder.start();
|
| 67 |
+
audioChunks = [];
|
| 68 |
+
startTime = Date.now();
|
| 69 |
+
document.getElementById("status").innerText = "Recording: 00:00";
|
| 70 |
+
timerInterval = setInterval(updateTimer, 1000);
|
| 71 |
+
mediaRecorder.ondataavailable = event => {
|
| 72 |
+
audioChunks.push(event.data);
|
| 73 |
+
};
|
| 74 |
+
mediaRecorder.onstop = () => {
|
| 75 |
+
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
|
| 76 |
+
const audioBase64 = blobToBase64(audioBlob).then(base64 => {
|
| 77 |
+
window.parent.postMessage({ type: 'audio', data: base64 }, '*');
|
| 78 |
+
});
|
| 79 |
+
clearInterval(timerInterval);
|
| 80 |
+
document.getElementById("status").innerText = "Recording stopped";
|
| 81 |
+
};
|
| 82 |
+
setTimeout(() => {
|
| 83 |
+
if (mediaRecorder.state !== "inactive") {
|
| 84 |
+
mediaRecorder.stop();
|
| 85 |
+
}
|
| 86 |
+
}, 120000); // Max 2 minutes = 120,000 ms
|
| 87 |
+
})
|
| 88 |
+
.catch(error => {
|
| 89 |
+
document.getElementById("status").innerText = "Error: " + error.message;
|
| 90 |
+
});
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
function stopRecording() {
|
| 94 |
+
if (mediaRecorder && mediaRecorder.state !== "inactive") {
|
| 95 |
+
mediaRecorder.stop();
|
| 96 |
+
}
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
function updateTimer() {
|
| 100 |
+
const elapsed = Math.floor((Date.now() - startTime) / 1000);
|
| 101 |
+
const minutes = Math.floor(elapsed / 60).toString().padStart(2, '0');
|
| 102 |
+
const seconds = (elapsed % 60).toString().padStart(2, '0');
|
| 103 |
+
document.getElementById("status").innerText = `Recording: ${minutes}:${seconds}`;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
function blobToBase64(blob) {
|
| 107 |
+
return new Promise((resolve) => {
|
| 108 |
+
const reader = new FileReader();
|
| 109 |
+
reader.onloadend = () => resolve(reader.result.split(',')[1]);
|
| 110 |
+
reader.readAsDataURL(blob);
|
| 111 |
+
});
|
| 112 |
+
}
|
| 113 |
+
</script>
|
| 114 |
+
<button onclick="startRecording()">Start Recording</button>
|
| 115 |
+
<button onclick="stopRecording()">Stop Recording</button>
|
| 116 |
+
<p id="status">Press Start to record</p>
|
| 117 |
+
"""
|
| 118 |
+
|
| 119 |
+
# Embed the recorder
|
| 120 |
+
audio_data = None
|
| 121 |
+
if html(audio_recorder_html, height=200):
|
| 122 |
+
message = st.session_state.get("message", None)
|
| 123 |
+
if message and message["type"] == "audio":
|
| 124 |
+
audio_data = message["data"]
|
| 125 |
+
|
| 126 |
+
if audio_data:
|
| 127 |
+
audio_path = save_audio(audio_data, "/tmp/recorded_audio.wav")
|
| 128 |
+
st.success("Audio recorded and saved as 'recorded_audio.wav'!")
|
| 129 |
+
# HTML5 audio player with controls
|
| 130 |
+
audio_player_html = f"""
|
| 131 |
+
<audio controls>
|
| 132 |
+
<source src="data:audio/wav;base64,{base64.b64encode(open(audio_path, 'rb').read()).decode()}" type="audio/wav">
|
| 133 |
+
Your browser does not support the audio element.
|
| 134 |
+
</audio>
|
| 135 |
+
"""
|
| 136 |
+
st.markdown("### Listen to Recorded Audio:")
|
| 137 |
+
html(audio_player_html)
|
| 138 |
+
|
| 139 |
+
def on_message(message):
|
| 140 |
+
st.session_state["message"] = message
|
| 141 |
+
|
| 142 |
+
st.session_state["on_message"] = on_message
|