martinoyovo's picture
Update
eb2cf07
#!/usr/bin/env python3
"""
Gradio Interface for Voice Sentiment Analysis
Wav2Vec 2.0 + BERT Pipeline
"""
import gradio as gr
import pandas as pd
import os
from utils import custom_css
from voice_sentiment import VoiceSentimentAnalyzer
# Initialize model (once)
print("Loading models...")
analyzer = VoiceSentimentAnalyzer()
print("Models ready!")
def analyze_audio_file(audio_file):
"""Analyze an uploaded audio file"""
if audio_file is None:
return "No audio file provided", "", "", ""
try:
# Analyze the call
result = analyzer.analyze_call(audio_file)
# Format results
transcription = result['transcription']
sentiment = result['sentiment']
score = f"{result['score']:.2f}"
satisfaction = result['satisfaction']
# Emoji based on sentiment
emoji_map = {
"POSITIVE": "😊",
"NEGATIVE": "😠",
"NEUTRAL": "😐"
}
emoji = emoji_map.get(sentiment, "❓")
status = f"Analysis completed {emoji}"
return status, transcription, sentiment, score, satisfaction
except Exception as e:
error_msg = f"Analysis error: {str(e)}"
return error_msg, "", "", "", ""
def analyze_batch_files(files):
"""Analyze multiple audio files"""
if not files:
return "No files provided", None
try:
results = []
for file in files:
result = analyzer.analyze_call(file.name)
results.append({
"File": os.path.basename(file.name),
"Transcription": result['transcription'][:100] + "..." if len(result['transcription']) > 100 else result['transcription'],
"Sentiment": result['sentiment'],
"Score": round(result['score'], 2),
"Satisfaction": result['satisfaction']
})
# Create DataFrame for display
df = pd.DataFrame(results)
csv_filename = "analysis_results.csv"
print(f"Saving {len(df)} rows to CSV...")
df.to_csv(csv_filename, index=False)
print(f"CSV saved successfully") #
# Verify CSV was created and has content
if os.path.exists(csv_filename): # ← NEW DEBUG BLOCK
file_size = os.path.getsize(csv_filename)
print(f"CSV file exists, size: {file_size} bytes")
else:
print("CSV file was not created!")
# Statistics
total = len(results)
positive = len([r for r in results if r['Sentiment'] == 'POSITIVE'])
negative = len([r for r in results if r['Sentiment'] == 'NEGATIVE'])
neutral = len([r for r in results if r['Sentiment'] == 'NEUTRAL'])
stats = f"""πŸ“Š Statistics:
β€’ Total: {total} calls
β€’ Positive: {positive} ({positive/total*100:.1f}%)
β€’ Negative: {negative} ({negative/total*100:.1f}%)
β€’ Neutral: {neutral} ({neutral/total*100:.1f}%)"""
return stats, df
except Exception as e:
error_msg = f"Analysis error: {str(e)}"
return error_msg, None
# Gradio Interface
with gr.Blocks(title="Voice Sentiment Analysis", theme=gr.themes.Soft(), css=custom_css) as app:
gr.Markdown("""
# Voice Sentiment Analysis System
### Wav2Vec 2.0 + BERT Pipeline
Automatically analyze customer call sentiment and classify satisfaction.
""")
with gr.Tabs():
# Tab 1: Single file analysis
with gr.Tab("Single File"):
gr.Markdown("### Analyze one voice call")
with gr.Row():
with gr.Column():
audio_input = gr.Audio(
type="filepath",
label="Upload your audio file"
)
analyze_btn = gr.Button(
"Analyze",
variant="primary",
size="lg"
)
with gr.Column():
status_output = gr.Textbox(
label="πŸ“Š Status",
interactive=False
)
transcription_output = gr.Textbox(
label="πŸ“ Transcription",
lines=3,
interactive=False
)
with gr.Row():
sentiment_output = gr.Textbox(
label="🎭 Sentiment",
interactive=False
)
score_output = gr.Textbox(
label="🎯 Confidence Score",
interactive=False
)
satisfaction_output = gr.Textbox(
label="😊 Customer Satisfaction",
interactive=False
)
# Tab 2: Multiple files analysis
with gr.Tab("Multiple Files"):
gr.Markdown("### Analyze multiple calls in batch")
files_input = gr.File(
file_count="multiple",
file_types=[".wav", ".mp3", ".m4a"],
label="Upload your audio files"
)
batch_analyze_btn = gr.Button(
"Analyze All",
variant="primary",
size="lg"
)
batch_status = gr.Textbox(
label="Statistics",
lines=6,
interactive=False
)
results_table = gr.Dataframe(
label="Detailed Results",
interactive=False
)
# Tab 3: Information
with gr.Tab("Information"):
gr.Markdown("""
### How it works?
**3-step pipeline:**
1. **Audio β†’ Text**: Transcription with Wav2Vec 2.0
2. **Text β†’ Sentiment**: Analysis with multilingual BERT
3. **Classification**: Customer satisfaction (Satisfied/Dissatisfied/Neutral)
### Supported formats
- WAV (recommended)
- MP3
- M4A
### Classifications
- **😊 Satisfied**: Positive sentiment with high confidence
- **😠 Dissatisfied**: Negative sentiment with high confidence
- **😐 Neutral**: Neutral sentiment or low confidence
### Tips
- Clear audio quality recommended
- Optimal duration: 10 seconds to 2 minutes
- Avoid excessive background noise
""")
# Event connections
analyze_btn.click(
fn=analyze_audio_file,
inputs=[audio_input],
outputs=[status_output, transcription_output, sentiment_output, score_output, satisfaction_output]
)
batch_analyze_btn.click(
fn=analyze_batch_files,
inputs=[files_input],
outputs=[batch_status, results_table]
)
# Launch the application
if __name__ == "__main__":
app.launch(
share=True, # Creates a public link
server_name="0.0.0.0", # Accessible from other machines
server_port=7860
)