temp12821 commited on
Commit
2aa238a
ยท
1 Parent(s): 40f2bca

UI ready with pie and timeline graph

Browse files

do graphs pie aur timeline with emojies
saara UI tyar hai bas logic karna hai ab

Files changed (8) hide show
  1. .gitattributes +1 -0
  2. app.py +0 -7
  3. input/README.md +5 -0
  4. input/test.wav +3 -0
  5. main.py +0 -6
  6. pyproject.toml +2 -0
  7. requirements.txt +2 -0
  8. streamlit_app.py +366 -27
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.wav filter=lfs diff=lfs merge=lfs -text
app.py DELETED
@@ -1,7 +0,0 @@
1
- from fastapi import FastAPI
2
-
3
- app = FastAPI()
4
-
5
- @app.get("/")
6
- def greet_json():
7
- return {"Hello": "World!"}
 
 
 
 
 
 
 
 
input/README.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # Sample Audio Files
2
+
3
+ Place your sample audio file here named `sample_audio.wav` or `sample_audio.mp3`
4
+
5
+ This file will be used as the example file in the application.
input/test.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:876585f42dfcf9dbe504257cd87d45ff29e8c326bb4919c0ce99e1c2877ba343
3
+ size 2385836
main.py DELETED
@@ -1,6 +0,0 @@
1
- def main():
2
- print("Hello from audiosentiment!")
3
-
4
-
5
- if __name__ == "__main__":
6
- main()
 
 
 
 
 
 
 
pyproject.toml CHANGED
@@ -6,6 +6,8 @@ readme = "README.md"
6
  requires-python = ">=3.10"
7
  dependencies = [
8
  "flask>=3.1.2",
 
 
9
  "requests>=2.32.5",
10
  "streamlit>=1.54.0",
11
  ]
 
6
  requires-python = ">=3.10"
7
  dependencies = [
8
  "flask>=3.1.2",
9
+ "pandas>=2.3.3",
10
+ "plotly>=6.5.2",
11
  "requests>=2.32.5",
12
  "streamlit>=1.54.0",
13
  ]
requirements.txt CHANGED
@@ -3,3 +3,5 @@ uvicorn[standard]
3
  flask
4
  streamlit
5
  requests
 
 
 
3
  flask
4
  streamlit
5
  requests
6
+ pandas
7
+ plotly
streamlit_app.py CHANGED
@@ -1,38 +1,377 @@
1
  import streamlit as st
2
  import requests
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
- st.title("Flask API Client ๐Ÿš€")
5
- st.write("This app calls the Flask HelloWorld endpoint and displays the response")
 
6
 
7
  # Flask API URL
8
- import os
9
- FLASK_URL = os.getenv("FLASK_URL", "http://localhost:5000/helloworld")
10
 
11
- st.markdown("---")
 
12
 
13
- if st.button("Call Flask API"):
14
- try:
15
- with st.spinner("Calling Flask API..."):
16
- response = requests.get(FLASK_URL)
17
-
18
- if response.status_code == 200:
19
- st.success("API call successful! โœ…")
20
- data = response.json()
21
-
22
- # Display response in a nice format
23
- st.subheader("Response:")
24
- st.json(data)
25
-
26
- # Also display as text
27
- st.info(f"Message: {data.get('message', 'N/A')}")
28
- st.info(f"Status: {data.get('status', 'N/A')}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  else:
30
- st.error(f"Error: Received status code {response.status_code}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- except requests.exceptions.ConnectionError:
33
- st.error("โŒ Could not connect to Flask server. Make sure it's running on port 5000!")
34
- except Exception as e:
35
- st.error(f"An error occurred: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
 
37
  st.markdown("---")
38
- st.caption("Make sure to run Flask app first: `python flask_app.py`")
 
1
  import streamlit as st
2
  import requests
3
+ import pandas as pd
4
+ import plotly.express as px
5
+ import plotly.graph_objects as go
6
+ from datetime import datetime
7
+ import os
8
+
9
+ # Page config
10
+ st.set_page_config(
11
+ page_title="Audio Sentiment Analysis",
12
+ page_icon="๐ŸŽค",
13
+ layout="wide"
14
+ )
15
 
16
+ # Title
17
+ st.title("๐ŸŽค Audio Sentiment Analysis Dashboard")
18
+ st.markdown("Analyze emotions from audio files with timeline visualization")
19
 
20
  # Flask API URL
21
+ FLASK_URL = os.getenv("FLASK_URL", "http://localhost:5000")
 
22
 
23
+ # Create tabs
24
+ tab1, tab2 = st.tabs(["๐Ÿ“ Test File Analysis", "๐ŸŽ™๏ธ Audio Input Analysis"])
25
 
26
+ # ============================================
27
+ # TAB 1: Test File Analysis
28
+ # ============================================
29
+ with tab1:
30
+ st.header("๐Ÿ“ Test File Analysis")
31
+ st.markdown("Upload a pre-recorded audio file for sentiment analysis")
32
+
33
+ # File selection option
34
+ file_option = st.radio(
35
+ "Choose audio source:",
36
+ options=["๐Ÿ“ Upload Your File", "๐ŸŽฏ Try Example File"],
37
+ horizontal=True,
38
+ help="Select whether to upload your own file or use the example"
39
+ )
40
+
41
+ audio_file = None
42
+ file_name = None
43
+
44
+ # Upload or Example file logic
45
+ if file_option == "๐Ÿ“ Upload Your File":
46
+ uploaded_file = st.file_uploader(
47
+ "Choose an audio file",
48
+ type=["wav", "mp3", "ogg", "flac", "m4a"],
49
+ help="Supported formats: WAV, MP3, OGG, FLAC, M4A"
50
+ )
51
+ if uploaded_file is not None:
52
+ audio_file = uploaded_file
53
+ file_name = uploaded_file.name
54
+ st.success(f"โœ… File uploaded: {uploaded_file.name}")
55
+
56
+ else: # Example file
57
+ example_path = "input/test.wav"
58
+ if os.path.exists(example_path):
59
+ audio_file = open(example_path, 'rb')
60
+ file_name = "test.wav"
61
+ st.info("๐Ÿ“Œ Using example audio file: test.wav")
62
  else:
63
+ st.warning("โš ๏ธ Example file not found in input/ folder")
64
+
65
+ # Show analyze button
66
+ analyze_btn = st.button("๐Ÿ” Analyze Audio", type="primary", use_container_width=True, disabled=(audio_file is None))
67
+
68
+ # Display audio player and file info if file is selected
69
+ if audio_file is not None:
70
+ # Audio player
71
+ st.subheader("๐ŸŽต Audio Preview")
72
+ st.audio(audio_file)
73
+
74
+ # File info
75
+ with st.expander("๐Ÿ“Š File Information"):
76
+ col1, col2, col3 = st.columns(3)
77
+ with col1:
78
+ st.metric("File Name", file_name)
79
+ with col2:
80
+ if hasattr(audio_file, 'size'):
81
+ st.metric("File Size", f"{audio_file.size / 1024:.2f} KB")
82
+ else:
83
+ st.metric("File Size", "N/A")
84
+ with col3:
85
+ if hasattr(audio_file, 'type'):
86
+ st.metric("File Type", audio_file.type)
87
+ else:
88
+ st.metric("File Type", "WAV")
89
+
90
+ # Analysis Results Section (placeholder)
91
+ if analyze_btn and audio_file:
92
+ with st.spinner("๐Ÿ”„ Analyzing audio... Please wait..."):
93
+ # Placeholder for Flask API call
94
+ st.info("โš™๏ธ Processing audio through Flask API...")
95
+
96
+ st.success("โœ… Analysis Complete!")
97
+
98
+ # Results layout
99
+ st.markdown("---")
100
+ st.subheader("๐Ÿ“Š Emotion Analysis Results")
101
+
102
+ # Sample timeline data with emojis
103
+ emotion_emoji_map = {
104
+ 'Happy': '๐Ÿ˜Š',
105
+ 'Sad': '๐Ÿ˜ข',
106
+ 'Angry': '๐Ÿ˜ก',
107
+ 'Neutral': '๐Ÿ˜'
108
+ }
109
+
110
+ sample_timeline = pd.DataFrame({
111
+ 'Time (s)': ['00:00', '00:05', '00:12', '00:20', '00:30', '00:40'],
112
+ 'Emotion': ['Neutral', 'Happy', 'Sad', 'Happy', 'Angry', 'Neutral'],
113
+ 'Confidence': [0.85, 0.92, 0.78, 0.88, 0.75, 0.90]
114
+ })
115
+
116
+ # Add emoji column
117
+ sample_timeline['Emoji'] = sample_timeline['Emotion'].map(emotion_emoji_map)
118
+
119
+ # Calculate metrics
120
+ total_duration = "00:45"
121
+ unique_emotions = sample_timeline['Emotion'].nunique()
122
+ dominant_emotion = sample_timeline['Emotion'].mode()[0]
123
+ dominant_emoji = emotion_emoji_map[dominant_emotion]
124
+
125
+ # Metrics
126
+ col1, col2, col3 = st.columns(3)
127
+ with col1:
128
+ st.metric("Total Duration", total_duration, help="Audio length")
129
+ with col2:
130
+ st.metric("Emotions Detected", unique_emotions, help="Number of unique emotions")
131
+ with col3:
132
+ st.metric("Dominant Emotion", f"{dominant_emoji} {dominant_emotion}", help="Most frequent emotion")
133
+
134
+ st.markdown("---")
135
+
136
+ # Layout: Timeline and Pie Chart
137
+ col1, col2 = st.columns([2, 1])
138
+
139
+ with col1:
140
+ st.subheader("โฑ๏ธ Emotion Timeline")
141
+
142
+ # Bar chart with emojis
143
+ fig_timeline = go.Figure()
144
+
145
+ colors = {
146
+ 'Happy': '#FFD700',
147
+ 'Sad': '#4169E1',
148
+ 'Angry': '#DC143C',
149
+ 'Neutral': '#808080'
150
+ }
151
+
152
+ for emotion in sample_timeline['Emotion'].unique():
153
+ emotion_data = sample_timeline[sample_timeline['Emotion'] == emotion]
154
+ fig_timeline.add_trace(go.Bar(
155
+ x=emotion_data['Time (s)'],
156
+ y=emotion_data['Confidence'],
157
+ name=f"{emotion_emoji_map[emotion]} {emotion}",
158
+ marker_color=colors[emotion],
159
+ text=[emotion_emoji_map[emotion]] * len(emotion_data),
160
+ textposition='outside',
161
+ textfont=dict(size=20)
162
+ ))
163
+
164
+ fig_timeline.update_layout(
165
+ xaxis_title="Time",
166
+ yaxis_title="Confidence",
167
+ yaxis_range=[0, 1.1],
168
+ barmode='group',
169
+ height=400,
170
+ showlegend=True,
171
+ hovermode='x unified'
172
+ )
173
+
174
+ st.plotly_chart(fig_timeline, use_container_width=True)
175
+
176
+ with col2:
177
+ st.subheader("๐Ÿ“Š Distribution")
178
+
179
+ # Pie chart for emotion distribution
180
+ emotion_counts = sample_timeline['Emotion'].value_counts()
181
+
182
+ fig_pie = go.Figure(data=[go.Pie(
183
+ labels=[f"{emotion_emoji_map[e]} {e}" for e in emotion_counts.index],
184
+ values=emotion_counts.values,
185
+ marker=dict(colors=[colors[e] for e in emotion_counts.index]),
186
+ textinfo='percent+label',
187
+ textfont=dict(size=12),
188
+ hole=0.3
189
+ )])
190
+
191
+ fig_pie.update_layout(
192
+ height=400,
193
+ showlegend=False
194
+ )
195
 
196
+ st.plotly_chart(fig_pie, use_container_width=True)
197
+
198
+ # Detailed Timeline Table
199
+ st.subheader("๐Ÿ“‹ Detailed Timeline")
200
+ display_df = sample_timeline[['Time (s)', 'Emoji', 'Emotion', 'Confidence']].copy()
201
+ display_df['Confidence'] = display_df['Confidence'].apply(lambda x: f"{x:.2%}")
202
+ st.dataframe(
203
+ display_df,
204
+ use_container_width=True,
205
+ hide_index=True
206
+ )
207
+
208
+ # ============================================
209
+ # TAB 2: Audio Input Analysis (Live Recording)
210
+ # ============================================
211
+ with tab2:
212
+ st.header("๐ŸŽ™๏ธ Live Audio Input Analysis")
213
+ st.markdown("Record audio in real-time for sentiment analysis")
214
+
215
+ # Recording controls
216
+ col1, col2, col3 = st.columns(3)
217
+
218
+ with col1:
219
+ record_btn = st.button("๐Ÿ”ด Start Recording", type="primary", use_container_width=True)
220
+ with col2:
221
+ stop_btn = st.button("โน๏ธ Stop Recording", use_container_width=True)
222
+ with col3:
223
+ analyze_record_btn = st.button("๐Ÿ” Analyze Recording", use_container_width=True)
224
+
225
+ # Recording status
226
+ if record_btn:
227
+ st.warning("๐Ÿ”ด Recording... (This feature will be implemented)")
228
+
229
+ if stop_btn:
230
+ st.info("โน๏ธ Recording stopped")
231
+
232
+ # Audio input section
233
+ st.subheader("๐ŸŽค Audio Input Settings")
234
+
235
+ col1, col2 = st.columns(2)
236
+
237
+ with col1:
238
+ sample_rate = st.selectbox(
239
+ "Sample Rate",
240
+ options=[16000, 22050, 44100, 48000],
241
+ index=0,
242
+ help="Audio sample rate in Hz"
243
+ )
244
+
245
+ with col2:
246
+ channels = st.selectbox(
247
+ "Channels",
248
+ options=["Mono", "Stereo"],
249
+ index=0,
250
+ help="Audio channel configuration"
251
+ )
252
+
253
+ # Recorded audio preview (placeholder)
254
+ st.subheader("๐ŸŽต Recorded Audio Preview")
255
+ st.info("๐Ÿ“ No recording available yet. Click 'Start Recording' to begin.")
256
+
257
+ # Analysis results (placeholder)
258
+ if analyze_record_btn:
259
+ with st.spinner("๐Ÿ”„ Analyzing recorded audio..."):
260
+ st.info("โš™๏ธ Processing audio through Flask API...")
261
+
262
+ st.success("โœ… Analysis Complete!")
263
+
264
+ # Results layout
265
+ st.markdown("---")
266
+ st.subheader("๐Ÿ“Š Emotion Analysis Results")
267
+
268
+ # Emotion emoji mapping
269
+ emotion_emoji_map = {
270
+ 'Happy': '๐Ÿ˜Š',
271
+ 'Sad': '๐Ÿ˜ข',
272
+ 'Angry': '๐Ÿ˜ก',
273
+ 'Neutral': '๐Ÿ˜'
274
+ }
275
+
276
+ # Sample data for recorded audio
277
+ sample_data = pd.DataFrame({
278
+ 'Time (s)': ['00:00', '00:08', '00:15', '00:22', '00:28'],
279
+ 'Emotion': ['Neutral', 'Happy', 'Neutral', 'Sad', 'Neutral'],
280
+ 'Confidence': [0.88, 0.85, 0.90, 0.72, 0.87]
281
+ })
282
+
283
+ # Add emoji column
284
+ sample_data['Emoji'] = sample_data['Emotion'].map(emotion_emoji_map)
285
+
286
+ # Calculate metrics
287
+ total_duration = "00:30"
288
+ unique_emotions = sample_data['Emotion'].nunique()
289
+ dominant_emotion = sample_data['Emotion'].mode()[0]
290
+ dominant_emoji = emotion_emoji_map[dominant_emotion]
291
+
292
+ # Metrics
293
+ col1, col2, col3 = st.columns(3)
294
+ with col1:
295
+ st.metric("Recording Duration", total_duration, help="Length of recording")
296
+ with col2:
297
+ st.metric("Emotions Detected", unique_emotions, help="Number of unique emotions")
298
+ with col3:
299
+ st.metric("Dominant Emotion", f"{dominant_emoji} {dominant_emotion}", help="Most frequent emotion")
300
+
301
+ st.markdown("---")
302
+
303
+ # Layout: Timeline and Pie Chart
304
+ col1, col2 = st.columns([2, 1])
305
+
306
+ with col1:
307
+ st.subheader("โฑ๏ธ Emotion Timeline")
308
+
309
+ # Bar chart with emojis
310
+ fig_timeline = go.Figure()
311
+
312
+ colors = {
313
+ 'Happy': '#FFD700',
314
+ 'Sad': '#4169E1',
315
+ 'Angry': '#DC143C',
316
+ 'Neutral': '#808080'
317
+ }
318
+
319
+ for emotion in sample_data['Emotion'].unique():
320
+ emotion_data = sample_data[sample_data['Emotion'] == emotion]
321
+ fig_timeline.add_trace(go.Bar(
322
+ x=emotion_data['Time (s)'],
323
+ y=emotion_data['Confidence'],
324
+ name=f"{emotion_emoji_map[emotion]} {emotion}",
325
+ marker_color=colors[emotion],
326
+ text=[emotion_emoji_map[emotion]] * len(emotion_data),
327
+ textposition='outside',
328
+ textfont=dict(size=20)
329
+ ))
330
+
331
+ fig_timeline.update_layout(
332
+ xaxis_title="Time",
333
+ yaxis_title="Confidence",
334
+ yaxis_range=[0, 1.1],
335
+ barmode='group',
336
+ height=400,
337
+ showlegend=True,
338
+ hovermode='x unified'
339
+ )
340
+
341
+ st.plotly_chart(fig_timeline, use_container_width=True)
342
+
343
+ with col2:
344
+ st.subheader("๐Ÿ“Š Distribution")
345
+
346
+ # Pie chart for emotion distribution
347
+ emotion_counts = sample_data['Emotion'].value_counts()
348
+
349
+ fig_pie = go.Figure(data=[go.Pie(
350
+ labels=[f"{emotion_emoji_map[e]} {e}" for e in emotion_counts.index],
351
+ values=emotion_counts.values,
352
+ marker=dict(colors=[colors[e] for e in emotion_counts.index]),
353
+ textinfo='percent+label',
354
+ textfont=dict(size=12),
355
+ hole=0.3
356
+ )])
357
+
358
+ fig_pie.update_layout(
359
+ height=400,
360
+ showlegend=False
361
+ )
362
+
363
+ st.plotly_chart(fig_pie, use_container_width=True)
364
+
365
+ # Detailed Timeline Table
366
+ st.subheader("๐Ÿ“‹ Detailed Timeline")
367
+ display_df = sample_data[['Time (s)', 'Emoji', 'Emotion', 'Confidence']].copy()
368
+ display_df['Confidence'] = display_df['Confidence'].apply(lambda x: f"{x:.2%}")
369
+ st.dataframe(
370
+ display_df,
371
+ use_container_width=True,
372
+ hide_index=True
373
+ )
374
 
375
+ # Footer
376
  st.markdown("---")
377
+ st.caption("๐Ÿ”ง Powered by Flask + Streamlit | Audio Sentiment Analysis")