Приложение Streamlit продолжает обработку звука после нажатия кнопки прекращения экспериментаPython

Программы на Python
Ответить
Anonymous
 Приложение Streamlit продолжает обработку звука после нажатия кнопки прекращения эксперимента

Сообщение Anonymous »

Я разрабатываю приложение Streamlit для эксперимента с голосовым взаимодействием. Приложение позволяет участникам записывать звук, который затем обрабатывается с помощью STT (преобразование речи в текст), LangChain для обработки текста и TTS (преобразование текста в речь). Участники могут прекратить эксперимент в любое время, используя кнопку «Прекратить эксперимент». Однако я столкнулся с проблемой, из-за которой даже после нажатия кнопки завершения обработка звука продолжает работать.

Код: Выделить всё

import streamlit as st
from datetime import datetime
from pathlib import Path
import json
from stt import STTProcessor
from process import LangChainProcessor
from tts import TTSProcessor
from dotenv import load_dotenv
import time

load_dotenv()

st.sidebar.page_link('app.py', label='Start Screen')

# Define constants
DATA_DIR = Path("experiment_data")
DATA_DIR.mkdir(exist_ok=True)

class ConversationLogger:
def __init__(self, save_dir=DATA_DIR):
self.save_dir = Path(save_dir)
self.save_dir.mkdir(exist_ok=True)
self.logs = []

def initialize_for_participant(self, participant_id):
self.participant_id = participant_id
self.log_file = self.save_dir / f"{participant_id}_conversations.json"
if self.log_file.exists():
with open(self.log_file, 'r', encoding='utf-8') as f:
self.logs = json.load(f)

def log_conversation(self, stt_text, tts_text):
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
entries = [
{"timestamp": timestamp, "text": stt_text, "role": "human"},
{"timestamp": timestamp, "text": tts_text, "role": "assistant"}
]
self.logs.extend(entries)

def save_to_file(self):
with open(self.log_file, 'w', encoding='utf-8') as f:
json.dump(self.logs, f, ensure_ascii=False, indent=2)

def format_for_llm(self):
"""Format conversation logs for LLM input"""
return "\n".join(
f"{entry['role']}: {entry['text']}"
for entry in self.logs[-10:]  # Use only the last 10 entries
)

def get_conversation_history(self):
"""Get complete conversation logs for Streamlit display"""
return self.logs

def handle_experiment_termination(logger):
"""Handle experiment termination"""
try:
# Save final conversation logs
logger.save_to_file()

# Save termination information
end_info = {
"participant_id": st.session_state.participant_id,
"end_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
with open(DATA_DIR / f"{st.session_state.participant_id}_end_info.json", 'w', encoding='utf-8') as f:
json.dump(end_info, f, ensure_ascii=False, indent=2)

# Clear session
for key in ['participant_id', 'logger']:
if key in st.session_state:
del st.session_state[key]

return True
except Exception as e:
st.error(f"Error occurred during experiment termination: {str(e)}")
return False

def main():

if st.session_state.get('experiment_ended', False):
st.switch_page("pages/experiment_complete.py")
return

st.title("🎤 Voice Conversation Experiment")
if 'participant_id' not in st.session_state:
st.warning("⚠️ Participant registration is required.")
return

experiment_mode = st.radio(
"Select experiment mode",
["Discourse Marker Mode", "Basic Mode"],
horizontal=True,  # Display horizontally
label_visibility="collapsed"   # Hide label
)

# Initialize logger and participant settings
if 'logger' not in st.session_state:
logger = ConversationLogger()
logger.initialize_for_participant(st.session_state.participant_id)
st.session_state.logger = logger

stt_processor = STTProcessor()
lang_processor = LangChainProcessor()
tts_processor = TTSProcessor()

st.write(f"Participant ID: {st.session_state.participant_id}")
audio_file = st.audio_input("Record audio", key="audio_recorder")

if audio_file and not st.session_state.get("experiment_ended", False):
if 'experiment_ended' in st.session_state and st.session_state.experiment_ended:
st.switch_page("pages/experiment_complete.py")
return

with st.spinner("🔄 Processing audio..."):
try:
# STT processing
audio_bytes = audio_file.read()
stt_text = stt_processor.transcribe_audio(audio_bytes)
if not stt_text:
st.error("Failed to convert audio to text. Please try again.")
return

st.success("🎯 Recognized Text")
st.write(f"💬 {stt_text}")

# LangChain processing
conversation_history = st.session_state.logger.format_for_llm()

if experiment_mode == "Basic Mode":
tts_text = lang_processor.process_text(stt_text, conversation_history, modify=False)
elif experiment_mode == "Discourse Marker Mode":
tts_text = lang_processor.process_text(stt_text, conversation_history, modify=True)

st.info("🤖 AI's Response")
st.write(f"💭 {tts_text}")

# Log conversation
st.session_state.logger.log_conversation(stt_text, tts_text)

# TTS processing
if 'experiment_ended' in st.session_state and st.session_state.experiment_ended:
st.switch_page("pages/experiment_complete.py")
return
tts_processor.speak_text(tts_text)

except Exception as e:
st.error(f"An error occurred during processing: {str(e)}")

# Display conversation logs - use complete history
st.markdown("---")
with st.expander("Check current conversation history", expanded=False):
if 'logger' in st.session_state:
st.json(st.session_state.logger.get_conversation_history())

with st.expander("End Experiment", expanded=False):
st.warning("Once the experiment ends, you will no longer be able to continue voice conversations.")
if st.button("End Experiment", type="primary"):
# Immediately update session state
st.session_state.experiment_ended = True
st.session_state.stop_processing = True  # Additional
try:
# Save final conversation logs
st.session_state.logger.save_to_file()

# Save termination information
end_info = {
"participant_id": st.session_state.participant_id,
"end_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
with open(DATA_DIR / f"{st.session_state.participant_id}_end_info.json", 'w', encoding='utf-8') as f:
json.dump(end_info, f, ensure_ascii=False, indent=2)

# Clear session
for key in ['participant_id', 'logger']:
st.session_state.pop(key, None)

st.

Буду очень признателен за любую помощь.
Я попытался реализовать асинхронную обработку или использовать состояние сеанса, чтобы предотвратить ненужный запуск обработки звука.

Подробнее здесь: https://stackoverflow.com/questions/791 ... -button-is
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»