Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -54,9 +54,8 @@ st.set_page_config(
|
|
54 |
)
|
55 |
|
56 |
|
57 |
-
|
58 |
def create_speech_component():
|
59 |
-
"""Create speech recognition component with
|
60 |
|
61 |
speech_recognition_html = """
|
62 |
<div style="padding: 20px;">
|
@@ -68,31 +67,24 @@ def create_speech_component():
|
|
68 |
<div id="status" style="margin: 10px 0; padding: 10px; background: #e8f5e9;">Ready</div>
|
69 |
<div id="output" style="white-space: pre-wrap; padding: 15px; background: #f5f5f5; min-height: 100px; max-height: 400px; overflow-y: auto;"></div>
|
70 |
|
71 |
-
<!-- Hidden input for Streamlit communication -->
|
72 |
-
<input type="hidden" id="transcript_value" name="transcript_value" value="">
|
73 |
-
|
74 |
<script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
|
76 |
const startButton = document.getElementById('start');
|
77 |
const stopButton = document.getElementById('stop');
|
78 |
const clearButton = document.getElementById('clear');
|
79 |
const status = document.getElementById('status');
|
80 |
const output = document.getElementById('output');
|
81 |
-
const transcriptInput = document.getElementById('transcript_value');
|
82 |
-
let fullTranscript = '';
|
83 |
|
84 |
-
// Set up recognition
|
85 |
recognition.continuous = true;
|
86 |
recognition.interimResults = true;
|
87 |
|
88 |
-
// Function to update transcript value
|
89 |
-
function updateTranscript(text) {
|
90 |
-
transcriptInput.value = text;
|
91 |
-
// Trigger a change event
|
92 |
-
const event = new Event('change', { bubbles: true });
|
93 |
-
transcriptInput.dispatchEvent(event);
|
94 |
-
}
|
95 |
-
|
96 |
startButton.onclick = () => {
|
97 |
recognition.start();
|
98 |
status.textContent = '🎤 Listening...';
|
@@ -105,13 +97,11 @@ def create_speech_component():
|
|
105 |
status.textContent = 'Stopped';
|
106 |
startButton.disabled = false;
|
107 |
stopButton.disabled = true;
|
108 |
-
updateTranscript(fullTranscript);
|
109 |
};
|
110 |
|
111 |
clearButton.onclick = () => {
|
112 |
-
|
113 |
output.textContent = '';
|
114 |
-
updateTranscript('');
|
115 |
};
|
116 |
|
117 |
recognition.onresult = (event) => {
|
@@ -122,14 +112,13 @@ def create_speech_component():
|
|
122 |
const transcript = event.results[i][0].transcript;
|
123 |
if (event.results[i].isFinal) {
|
124 |
finalTranscript += transcript + ' ';
|
125 |
-
|
126 |
-
updateTranscript(fullTranscript);
|
127 |
} else {
|
128 |
interimTranscript += transcript;
|
129 |
}
|
130 |
}
|
131 |
|
132 |
-
output.textContent =
|
133 |
output.scrollTop = output.scrollHeight;
|
134 |
};
|
135 |
|
@@ -139,7 +128,7 @@ def create_speech_component():
|
|
139 |
}
|
140 |
};
|
141 |
|
142 |
-
// Auto-start
|
143 |
window.addEventListener('load', () => {
|
144 |
setTimeout(() => startButton.click(), 1000);
|
145 |
});
|
@@ -149,27 +138,43 @@ def create_speech_component():
|
|
149 |
|
150 |
return components.html(speech_recognition_html, height=400)
|
151 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
def integrate_speech_component():
|
153 |
-
"""Integrate speech component with
|
154 |
if "voice_transcript" not in st.session_state:
|
155 |
st.session_state.voice_transcript = ""
|
|
|
|
|
156 |
|
157 |
-
# Create
|
|
|
|
|
|
|
158 |
transcript_container = st.empty()
|
159 |
-
|
160 |
-
# Create the component and get value from hidden input
|
161 |
-
component = create_speech_component()
|
162 |
|
163 |
-
#
|
164 |
-
if
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
|
|
|
|
|
|
|
|
173 |
|
174 |
return st.session_state.voice_transcript
|
175 |
|
@@ -988,7 +993,6 @@ def get_media_html(media_path, media_type="video", width="100%"):
|
|
988 |
def set_transcript(text):
|
989 |
"""Set transcript in session state."""
|
990 |
st.session_state.voice_transcript = text
|
991 |
-
|
992 |
def main():
|
993 |
st.sidebar.markdown("### 🚲BikeAI🏆 Claude and GPT Multi-Agent Research AI")
|
994 |
|
@@ -999,18 +1003,14 @@ def main():
|
|
999 |
if tab_main == "🎤 Voice Input":
|
1000 |
st.subheader("Voice Recognition")
|
1001 |
|
1002 |
-
# Debug toggle
|
1003 |
-
show_debug = st.checkbox("Show Debug Info")
|
1004 |
-
|
1005 |
try:
|
1006 |
-
#
|
1007 |
current_transcript = integrate_speech_component()
|
1008 |
|
1009 |
-
|
1010 |
-
|
1011 |
-
st.write("Current Transcript:", current_transcript)
|
1012 |
|
1013 |
-
# Process buttons
|
1014 |
if current_transcript:
|
1015 |
col1, col2, col3 = st.columns(3)
|
1016 |
|
@@ -1034,8 +1034,6 @@ def main():
|
|
1034 |
|
1035 |
except Exception as e:
|
1036 |
st.error(f"Error in voice input: {str(e)}")
|
1037 |
-
if show_debug:
|
1038 |
-
st.exception(e)
|
1039 |
|
1040 |
|
1041 |
# Always show file manager in sidebar
|
|
|
54 |
)
|
55 |
|
56 |
|
|
|
57 |
def create_speech_component():
|
58 |
+
"""Create speech recognition component with JavaScript function to get transcript."""
|
59 |
|
60 |
speech_recognition_html = """
|
61 |
<div style="padding: 20px;">
|
|
|
67 |
<div id="status" style="margin: 10px 0; padding: 10px; background: #e8f5e9;">Ready</div>
|
68 |
<div id="output" style="white-space: pre-wrap; padding: 15px; background: #f5f5f5; min-height: 100px; max-height: 400px; overflow-y: auto;"></div>
|
69 |
|
|
|
|
|
|
|
70 |
<script>
|
71 |
+
let currentTranscript = '';
|
72 |
+
|
73 |
+
// Function that Streamlit can call to get current transcript
|
74 |
+
function getCurrentTranscript() {
|
75 |
+
return currentTranscript;
|
76 |
+
}
|
77 |
+
|
78 |
const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
|
79 |
const startButton = document.getElementById('start');
|
80 |
const stopButton = document.getElementById('stop');
|
81 |
const clearButton = document.getElementById('clear');
|
82 |
const status = document.getElementById('status');
|
83 |
const output = document.getElementById('output');
|
|
|
|
|
84 |
|
|
|
85 |
recognition.continuous = true;
|
86 |
recognition.interimResults = true;
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
startButton.onclick = () => {
|
89 |
recognition.start();
|
90 |
status.textContent = '🎤 Listening...';
|
|
|
97 |
status.textContent = 'Stopped';
|
98 |
startButton.disabled = false;
|
99 |
stopButton.disabled = true;
|
|
|
100 |
};
|
101 |
|
102 |
clearButton.onclick = () => {
|
103 |
+
currentTranscript = '';
|
104 |
output.textContent = '';
|
|
|
105 |
};
|
106 |
|
107 |
recognition.onresult = (event) => {
|
|
|
112 |
const transcript = event.results[i][0].transcript;
|
113 |
if (event.results[i].isFinal) {
|
114 |
finalTranscript += transcript + ' ';
|
115 |
+
currentTranscript += transcript + ' ';
|
|
|
116 |
} else {
|
117 |
interimTranscript += transcript;
|
118 |
}
|
119 |
}
|
120 |
|
121 |
+
output.textContent = currentTranscript + (interimTranscript ? '... ' + interimTranscript : '');
|
122 |
output.scrollTop = output.scrollHeight;
|
123 |
};
|
124 |
|
|
|
128 |
}
|
129 |
};
|
130 |
|
131 |
+
// Auto-start on load
|
132 |
window.addEventListener('load', () => {
|
133 |
setTimeout(() => startButton.click(), 1000);
|
134 |
});
|
|
|
138 |
|
139 |
return components.html(speech_recognition_html, height=400)
|
140 |
|
141 |
+
def get_transcript():
|
142 |
+
"""Get current transcript from JavaScript."""
|
143 |
+
# Evaluate JavaScript to get current transcript
|
144 |
+
js_code = "getCurrentTranscript()"
|
145 |
+
try:
|
146 |
+
return components.eval_js(js_code)
|
147 |
+
except Exception as e:
|
148 |
+
st.error(f"Error getting transcript: {str(e)}")
|
149 |
+
return None
|
150 |
+
|
151 |
def integrate_speech_component():
|
152 |
+
"""Integrate speech component with timer-based polling."""
|
153 |
if "voice_transcript" not in st.session_state:
|
154 |
st.session_state.voice_transcript = ""
|
155 |
+
if "last_update" not in st.session_state:
|
156 |
+
st.session_state.last_update = time.time()
|
157 |
|
158 |
+
# Create the speech component
|
159 |
+
create_speech_component()
|
160 |
+
|
161 |
+
# Create placeholder for transcript display
|
162 |
transcript_container = st.empty()
|
|
|
|
|
|
|
163 |
|
164 |
+
# Check for updates every 10 seconds
|
165 |
+
if time.time() - st.session_state.last_update >= 10:
|
166 |
+
new_transcript = get_transcript()
|
167 |
+
if new_transcript and new_transcript != st.session_state.voice_transcript:
|
168 |
+
st.session_state.voice_transcript = new_transcript
|
169 |
+
st.session_state.last_update = time.time()
|
170 |
+
|
171 |
+
# Display current transcript
|
172 |
+
transcript_container.text_area(
|
173 |
+
"Voice Transcript:",
|
174 |
+
value=st.session_state.voice_transcript,
|
175 |
+
height=100,
|
176 |
+
key="transcript_display"
|
177 |
+
)
|
178 |
|
179 |
return st.session_state.voice_transcript
|
180 |
|
|
|
993 |
def set_transcript(text):
|
994 |
"""Set transcript in session state."""
|
995 |
st.session_state.voice_transcript = text
|
|
|
996 |
def main():
|
997 |
st.sidebar.markdown("### 🚲BikeAI🏆 Claude and GPT Multi-Agent Research AI")
|
998 |
|
|
|
1003 |
if tab_main == "🎤 Voice Input":
|
1004 |
st.subheader("Voice Recognition")
|
1005 |
|
|
|
|
|
|
|
1006 |
try:
|
1007 |
+
# Initialize speech component
|
1008 |
current_transcript = integrate_speech_component()
|
1009 |
|
1010 |
+
# Show last update time
|
1011 |
+
st.text(f"Last updated: {datetime.fromtimestamp(st.session_state.last_update).strftime('%H:%M:%S')}")
|
|
|
1012 |
|
1013 |
+
# Process buttons if we have a transcript
|
1014 |
if current_transcript:
|
1015 |
col1, col2, col3 = st.columns(3)
|
1016 |
|
|
|
1034 |
|
1035 |
except Exception as e:
|
1036 |
st.error(f"Error in voice input: {str(e)}")
|
|
|
|
|
1037 |
|
1038 |
|
1039 |
# Always show file manager in sidebar
|