YashsharmaPhD commited on
Commit
8941721
·
verified ·
1 Parent(s): e78469c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -127
app.py CHANGED
@@ -6,16 +6,20 @@ import seaborn as sns
6
  from pydub import AudioSegment
7
  from transformers import pipeline
8
  import os
9
- import matplotlib.patches as patches
10
  import librosa.display
11
- import whisper # Import Whisper for speech-to-text
 
12
 
13
  # Load pre-trained sentiment analysis model
14
  sentiment_analyzer = pipeline("sentiment-analysis")
15
 
16
- # Load Whisper model (small for faster performance)
17
  whisper_model = whisper.load_model("base")
18
 
 
 
 
 
19
  # Streamlit UI
20
  st.title("🎤 Audio Sentiment & Feature Analysis")
21
  st.write("Upload an MP3 file to analyze its sentiment and audio features.")
@@ -23,145 +27,45 @@ st.write("Upload an MP3 file to analyze its sentiment and audio features.")
23
  # Upload audio file
24
  uploaded_file = st.file_uploader("Choose an MP3 file", type=["mp3"])
25
 
26
- # Function to analyze sentiment over time
27
- def analyze_sentiment_over_time(y, sr, chunk_duration=10):
28
- """
29
- Splits audio into chunks, transcribes, and performs sentiment analysis.
30
-
31
- Args:
32
- y: The audio waveform.
33
- sr: Sample rate.
34
- chunk_duration: Duration of each chunk in seconds (default: 10 sec).
35
-
36
- Returns:
37
- A list of sentiment labels over time.
38
- """
39
- chunk_length = chunk_duration * sr # Convert chunk duration to samples
40
- total_chunks = len(y) // chunk_length # Number of chunks
41
- sentiment_labels = []
42
-
43
- for i in range(total_chunks):
44
- start_sample = i * chunk_length
45
- end_sample = start_sample + chunk_length
46
- chunk_audio = y[start_sample:end_sample]
47
-
48
- # Convert chunk to WAV
49
- temp_wav_path = f"temp_chunk_{i}.wav"
50
- librosa.output.write_wav(temp_wav_path, chunk_audio, sr)
51
 
52
- # Transcribe with Whisper
53
- result = whisper_model.transcribe(temp_wav_path)
54
- os.remove(temp_wav_path) # Remove temporary WAV file
55
-
56
- transcribed_text = result["text"]
57
-
58
- # Run sentiment analysis on transcribed text (if available)
59
- if transcribed_text.strip():
60
- sentiment_result = sentiment_analyzer(transcribed_text)
61
- sentiment_labels.append(sentiment_result[0]["label"])
62
- else:
63
- sentiment_labels.append("NEUTRAL")
64
 
65
- return sentiment_labels
 
66
 
67
- # Function to process audio and get sentiment
68
- def analyze_audio(file_path):
69
  # Convert MP3 to WAV
70
  audio = AudioSegment.from_mp3(file_path)
71
  wav_path = file_path.replace(".mp3", ".wav")
72
  audio.export(wav_path, format="wav")
73
 
74
- # Load audio
75
- y, sr = librosa.load(wav_path, sr=None)
76
-
77
- # Extract MFCCs (Mel-frequency cepstral coefficients)
78
- mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)
79
- mfccs_mean = np.mean(mfccs, axis=1)
80
-
81
- # Transcribe audio
82
  result = whisper_model.transcribe(wav_path)
83
  transcribed_text = result["text"]
84
 
85
- # Run sentiment analysis
86
- if transcribed_text.strip():
87
- sentiment_result = sentiment_analyzer(transcribed_text)
88
- else:
89
- sentiment_result = [{"label": "NEUTRAL", "score": 0.0}]
90
-
91
- os.remove(wav_path) # Remove WAV file after processing
92
- return y, sr, sentiment_result[0], mfccs, mfccs_mean, transcribed_text
93
-
94
- # Function to extract words from audio using Whisper
95
- def extract_words_from_audio(file_path):
96
- # Convert MP3 to WAV
97
- audio = AudioSegment.from_mp3(file_path)
98
- wav_path = file_path.replace(".mp3", ".wav")
99
- audio.export(wav_path, format="wav")
100
-
101
- # Transcribe audio using Whisper
102
- result = whisper_model.transcribe(wav_path, word_timestamps=True)
103
 
104
- # Extract words and timestamps
105
- words = []
106
- for segment in result['segments']:
107
- for word_info in segment['words']:
108
- words.append({"word": word_info['word'], "start_time": word_info['start'], "end_time": word_info['end']})
109
-
110
- os.remove(wav_path)
111
- return words, result['text']
112
-
113
- # Process and plot if a file is uploaded
114
- if uploaded_file:
115
- file_path = f"temp/{uploaded_file.name}"
116
- os.makedirs("temp", exist_ok=True) # Ensure temp directory exists
117
-
118
- with open(file_path, "wb") as f:
119
- f.write(uploaded_file.getbuffer())
120
-
121
- # Analyze sentiment & extract features
122
- y, sr, sentiment, mfccs, mfccs_mean, transcribed_text = analyze_audio(file_path)
123
-
124
- # Extract words from audio
125
- words_from_audio, _ = extract_words_from_audio(file_path)
126
-
127
- # Categorize words
128
- good_words = [w['word'] for w in words_from_audio if w['word'].lower() in ['good', 'excellent', 'positive', 'great', 'happy', 'success']]
129
- negative_words = [w['word'] for w in words_from_audio if w['word'].lower() in ['bad', 'negative', 'poor', 'angry', 'sad', 'failure']]
130
-
131
- # Determine sentiment color
132
- sentiment_label = sentiment['label']
133
- sentiment_color = "green" if sentiment_label == "POSITIVE" else "red"
134
-
135
- # Display sentiment
136
- st.subheader("📊 Sentiment Analysis Result")
137
- st.markdown(f"**Sentiment:** <span style='color:{sentiment_color}; font-size:20px;'>{sentiment_label}</span>", unsafe_allow_html=True)
138
- st.write(f"**Confidence:** {sentiment['score']:.2f}")
139
-
140
- # Analyze sentiment over time
141
- sentiment_scores = analyze_sentiment_over_time(y, sr)
142
- sentiment_numeric = [1 if s == "POSITIVE" else -1 for s in sentiment_scores]
143
-
144
- # Plot sentiment trend
145
- fig, ax = plt.subplots(figsize=(8, 4))
146
- ax.scatter(range(len(sentiment_numeric)), sentiment_numeric, c=sentiment_numeric, cmap="coolwarm")
147
- ax.set_title("Sentiment Trend (10-sec intervals)")
148
- ax.set_xticks(range(0, len(sentiment_scores), max(1, len(sentiment_scores)//5)))
149
- ax.set_yticks([-1, 1], labels=["Negative", "Positive"])
150
- st.pyplot(fig)
151
-
152
- # Display positive & negative words
153
- st.subheader("🗣️ Positive and Negative Words in Audio")
154
  col1, col2 = st.columns(2)
 
155
  with col1:
156
- st.markdown("### Good Words")
157
  st.write(", ".join(good_words) if good_words else "No good words detected.")
158
- with col2:
159
- st.markdown("### Negative Words")
160
- st.write(", ".join(negative_words) if negative_words else "No negative words detected.")
161
 
162
- # Display full transcription
163
- st.subheader("📝 Full Transcription")
164
- st.write(transcribed_text)
165
 
166
- # Clean up temp file
 
167
  os.remove(file_path)
 
 
6
  from pydub import AudioSegment
7
  from transformers import pipeline
8
  import os
 
9
  import librosa.display
10
+ import whisper
11
+ import textwrap
12
 
13
  # Load pre-trained sentiment analysis model
14
  sentiment_analyzer = pipeline("sentiment-analysis")
15
 
16
+ # Load Whisper model
17
  whisper_model = whisper.load_model("base")
18
 
19
+ # Positive & Negative Word Lists
20
+ positive_words = ["good", "excellent", "happy", "positive", "great", "success", "love", "joy", "fantastic"]
21
+ negative_words = ["bad", "poor", "angry", "negative", "sad", "failure", "hate", "terrible", "awful"]
22
+
23
  # Streamlit UI
24
  st.title("🎤 Audio Sentiment & Feature Analysis")
25
  st.write("Upload an MP3 file to analyze its sentiment and audio features.")
 
27
  # Upload audio file
28
  uploaded_file = st.file_uploader("Choose an MP3 file", type=["mp3"])
29
 
30
+ def extract_words_from_text(text):
31
+ """Extracts words and categorizes them as positive or negative."""
32
+ words = text.lower().split()
33
+ good_words = [word for word in words if word in positive_words]
34
+ bad_words = [word for word in words if word in negative_words]
35
+ return good_words, bad_words
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
+ if uploaded_file:
38
+ file_path = f"temp/{uploaded_file.name}"
39
+ os.makedirs("temp", exist_ok=True)
 
 
 
 
 
 
 
 
 
40
 
41
+ with open(file_path, "wb") as f:
42
+ f.write(uploaded_file.getbuffer())
43
 
 
 
44
  # Convert MP3 to WAV
45
  audio = AudioSegment.from_mp3(file_path)
46
  wav_path = file_path.replace(".mp3", ".wav")
47
  audio.export(wav_path, format="wav")
48
 
49
+ # Transcribe with Whisper
 
 
 
 
 
 
 
50
  result = whisper_model.transcribe(wav_path)
51
  transcribed_text = result["text"]
52
 
53
+ # Extract words and categorize them
54
+ good_words, bad_words = extract_words_from_text(transcribed_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
+ # Display Positive & Negative Words in a Table
57
+ st.subheader("🗣️ Positive & Negative Words in Transcription")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  col1, col2 = st.columns(2)
59
+
60
  with col1:
61
+ st.markdown("### Good Words")
62
  st.write(", ".join(good_words) if good_words else "No good words detected.")
 
 
 
63
 
64
+ with col2:
65
+ st.markdown("### Bad Words")
66
+ st.write(", ".join(bad_words) if bad_words else "No bad words detected.")
67
 
68
+ # Clean up temp files
69
+ os.remove(wav_path)
70
  os.remove(file_path)
71
+