abhishekjoel commited on
Commit
b619fdf
·
verified ·
1 Parent(s): e8e6f64

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -215
app.py CHANGED
@@ -1,223 +1,94 @@
1
- import streamlit as st
2
  import openai
 
3
  import os
4
- from datetime import datetime
5
- import json
6
- from dotenv import load_dotenv
7
- from pydub import AudioSegment
8
- import tempfile
9
- import math
10
- from pathlib import Path
11
- import shutil
12
-
13
- # Load environment variables
14
- load_dotenv()
15
-
16
- # Initialize OpenAI client
17
  openai.api_key = os.getenv("OPENAI_API_KEY")
18
 
19
- # Constants
20
- MAX_FILE_SIZE = 25 * 1024 * 1024 # 25MB in bytes (OpenAI API limit)
21
- CHUNK_LENGTH = 10 * 60 * 1000 # 10 minutes in milliseconds
22
-
23
- @st.cache_data
24
- def save_uploaded_file(uploaded_file):
25
- """Save uploaded file to a temporary directory and return the path"""
26
- try:
27
- temp_dir = tempfile.mkdtemp() # Create temporary directory
28
- file_extension = Path(uploaded_file.name).suffix # Get file extension
29
- temp_path = os.path.join(temp_dir, f"input_audio{file_extension}")
30
-
31
- # Save uploaded file
32
- with open(temp_path, "wb") as f:
33
- f.write(uploaded_file.getvalue())
34
-
35
- return temp_path, temp_dir
36
- except Exception as e:
37
- st.error(f"Error saving file: {str(e)}")
38
- return None, None
39
-
40
- def process_audio_file(file_path, temp_dir):
41
- """Process and potentially chunk the audio file"""
42
- try:
43
- # Load the audio file using pydub
44
- audio = AudioSegment.from_file(file_path)
45
-
46
- # If file size is under the limit, return as a single chunk
47
- if os.path.getsize(file_path) <= MAX_FILE_SIZE:
48
- return [file_path]
49
-
50
- # Otherwise, chunk the audio into smaller parts
51
- chunks = []
52
- total_length = len(audio)
53
- num_chunks = math.ceil(total_length / CHUNK_LENGTH)
54
-
55
- for i in range(num_chunks):
56
- start_time = i * CHUNK_LENGTH
57
- end_time = min((i + 1) * CHUNK_LENGTH, total_length)
58
- chunk = audio[start_time:end_time]
59
- chunk_path = os.path.join(temp_dir, f"chunk_{i}.mp3")
60
-
61
- # Export chunk with adjustments
62
- chunk = chunk.set_channels(1) # Convert to mono
63
- chunk = chunk.set_frame_rate(16000) # Set sample rate to 16kHz
64
- chunk.export(chunk_path, format="mp3", parameters=["-q:a", "0"])
65
-
66
- chunks.append(chunk_path)
67
- if not os.path.exists(chunk_path) or os.path.getsize(chunk_path) == 0:
68
- raise Exception(f"Failed to create chunk {i}")
69
-
70
- return chunks
71
- except Exception as e:
72
- st.error(f"Error processing audio: {str(e)}")
73
- return None
74
-
75
- def transcribe_audio_chunks(chunks):
76
- """Transcribe audio chunks and combine transcriptions"""
77
- all_segments = []
78
- current_time_offset = 0
79
-
80
- for i, chunk_path in enumerate(chunks):
81
- try:
82
- st.write(f"Processing chunk {i+1} of {len(chunks)}...")
83
- with open(chunk_path, "rb") as audio:
84
- transcript = openai.Audio.transcribe(
85
- model="whisper-1",
86
- file=audio,
87
- response_format="verbose_json"
88
- )
89
-
90
- for segment in transcript['segments']:
91
- segment['start'] += current_time_offset
92
- segment['end'] += current_time_offset
93
- all_segments.extend(transcript['segments'])
94
-
95
- # Update time offset for next chunk
96
- current_time_offset += len(AudioSegment.from_file(chunk_path)) / 1000 # Convert to seconds
97
-
98
- except Exception as e:
99
- st.error(f"Error in transcription of chunk {i+1}: {str(e)}")
100
- return None
101
-
102
- if all_segments:
103
- return all_segments
104
- return None
105
-
106
- def format_timestamp(seconds):
107
- """Convert seconds to HH:MM:SS format"""
108
- hours = int(seconds // 3600)
109
- minutes = int((seconds % 3600) // 60)
110
- seconds = int(seconds % 60)
111
- return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
112
-
113
- def generate_lesson_plan(transcript):
114
- """Generate a structured lesson plan from the transcript using GPT-4"""
115
- try:
116
- system_prompt = """You are an educational content expert. Generate a detailed lesson plan from the lecture transcript.
117
- The lesson plan should include:
118
- 1. Main Topics
119
- 2. Subtopics
120
- 3. Key Learning Objectives
121
- 4. Important Concepts
122
- Format the output in markdown with clear hierarchical structure."""
123
 
 
 
 
 
 
124
  response = openai.ChatCompletion.create(
125
- model="gpt-4-turbo",
126
  messages=[
127
- {"role": "system", "content": system_prompt},
128
- {"role": "user", "content": f"Generate a lesson plan from this transcript:\n{transcript}"}
129
- ],
130
- temperature=0.3,
131
- max_tokens=2000
132
  )
133
-
134
- return response.choices[0]['message']['content']
135
- except Exception as e:
136
- st.error(f"Error generating lesson plan: {str(e)}")
137
- return None
138
-
139
- def format_transcript_with_timestamps(segments):
140
- """Format transcript with timestamps in a readable format"""
141
- formatted_text = "# Lecture Transcript with Timestamps\n\n"
142
- for segment in segments:
143
- start_time = format_timestamp(segment['start'])
144
- formatted_text += f"**[{start_time}]** {segment['text']}\n\n"
145
- return formatted_text
146
-
147
- def cleanup_files(temp_dir):
148
- """Safely clean up temporary files"""
149
- try:
150
- if temp_dir and os.path.exists(temp_dir):
151
- shutil.rmtree(temp_dir)
152
- except Exception as e:
153
- st.warning(f"Warning: Could not clean up temporary files: {str(e)}")
154
-
155
- # Streamlit UI
156
- def main():
157
- st.set_page_config(page_title="Lecture Notes Generator", layout="wide")
158
-
159
- st.title("🎓 Lecture Notes Generator")
160
-
161
- col1, col2 = st.columns([1, 3])
162
-
163
- with col1:
164
- st.header("Upload Recording")
165
- uploaded_file = st.file_uploader("Choose an audio file", type=['mp3', 'wav', 'm4a'])
166
-
167
- if uploaded_file:
168
- st.audio(uploaded_file)
169
- file_size = uploaded_file.size / (1024 * 1024) # Convert to MB
170
- st.info(f"File size: {file_size:.2f} MB")
171
-
172
- if st.button("Generate Notes", type="primary", use_container_width=True):
173
- with col2:
174
- tab1, tab2 = st.tabs(["📝 Transcript", "📋 Lesson Plan"])
175
-
176
- with st.spinner("Processing audio..."):
177
- temp_path, temp_dir = save_uploaded_file(uploaded_file)
178
-
179
- if temp_path and temp_dir:
180
- try:
181
- chunks = process_audio_file(temp_path, temp_dir)
182
-
183
- if chunks:
184
- transcript_data = transcribe_audio_chunks(chunks)
185
-
186
- if transcript_data:
187
- formatted_transcript = format_transcript_with_timestamps(transcript_data)
188
- lesson_plan = generate_lesson_plan(formatted_transcript)
189
-
190
- with tab1:
191
- st.markdown(formatted_transcript)
192
- st.download_button(
193
- label="Download Transcript",
194
- data=formatted_transcript,
195
- file_name=f"transcript_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md",
196
- mime="text/markdown"
197
- )
198
-
199
- with tab2:
200
- if lesson_plan:
201
- st.markdown(lesson_plan)
202
- st.download_button(
203
- label="Download Lesson Plan",
204
- data=lesson_plan,
205
- file_name=f"lesson_plan_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md",
206
- mime="text/markdown"
207
- )
208
- finally:
209
- cleanup_files(temp_dir)
210
-
211
- if not uploaded_file:
212
- with col2:
213
- st.info("""
214
- 👈 Start by uploading an audio file on the left side.
215
-
216
- The system will automatically:
217
- 1. Transcribe the lecture with timestamps
218
- 2. Generate a structured lesson plan
219
- 3. Provide downloadable versions of both
220
- """)
221
-
222
- if __name__ == "__main__":
223
- main()
 
1
+ from llama_index import GPTSimpleVectorIndex, SimpleDirectoryReader
2
  import openai
3
+ import whisper
4
  import os
5
+ from typing import List
6
+ import streamlit as st
7
+
8
+ # Load Whisper Model
9
+ model = whisper.load_model("large-v3")
10
+
11
+ # Set OpenAI API Key
 
 
 
 
 
 
12
  openai.api_key = os.getenv("OPENAI_API_KEY")
13
 
14
+ # Llama Index for RAG PDF Handling
15
+ pdf_index = GPTSimpleVectorIndex([])
16
+
17
+ # Function to transcribe audio
18
+ def transcribe_audio(audio_file_path):
19
+ result = model.transcribe(audio_file_path)
20
+ return result["text"]
21
+
22
+ # Function to summarize lecture notes using ChatGPT-4
23
+ def generate_summary(text):
24
+ response = openai.ChatCompletion.create(
25
+ model="gpt-4",
26
+ messages=[
27
+ {"role": "system", "content": "You are an assistant that summarizes lecture notes."},
28
+ {"role": "user", "content": text}
29
+ ]
30
+ )
31
+ return response["choices"][0]["message"]["content"]
32
+
33
+ # Function to create lecture notes with timestamps
34
+ def create_structured_notes(transcription):
35
+ # Here you would process transcription and lesson plan to create structured notes.
36
+ # For simplicity, we assume the whole transcription is the lecture note.
37
+ return transcription
38
+
39
+ # Streamlit UI for Hugging Face Spaces
40
+ st.title("AI Summary")
41
+
42
+ # Upload Lecture Audio
43
+ st.subheader("Upload lecture")
44
+ audio_file = st.file_uploader("Upload lecture (.mp4, .mp3)", type=["mp4", "mp3"])
45
+
46
+ # Upload Lecture Link
47
+ st.subheader("or use lecture link")
48
+ lecture_link = st.text_input("URL")
49
+
50
+ # Generate button
51
+ generate_button = st.button("Generate")
52
+
53
+ if generate_button:
54
+ if audio_file:
55
+ # Save the uploaded audio file
56
+ file_path = f"./{audio_file.name}"
57
+ with open(file_path, "wb") as f:
58
+ f.write(audio_file.read())
59
+
60
+ # Transcribe the audio
61
+ transcription = transcribe_audio(file_path)
62
+
63
+ # Generate summary using GPT-4
64
+ summary = generate_summary(transcription)
65
+
66
+ # Create structured lecture notes
67
+ lecture_notes = create_structured_notes(transcription)
68
+
69
+ # Display Summary and Lecture Notes
70
+ st.subheader("Summary with Timestamp")
71
+ st.text(summary)
72
+
73
+ st.subheader("Generated Lecture Notes")
74
+ st.text(lecture_notes)
75
+ elif lecture_link:
76
+ st.error("Lecture link feature is not yet implemented.")
77
+ else:
78
+ st.error("Please upload an audio file or enter a lecture link.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ # Add a chat box for asking questions about the summary
81
+ st.subheader("Chat with the LLM")
82
+ user_query = st.text_input("Ask a Question about the Lecture")
83
+ if st.button("Ask Question"):
84
+ if user_query:
85
  response = openai.ChatCompletion.create(
86
+ model="gpt-4",
87
  messages=[
88
+ {"role": "system", "content": "You are an assistant that answers questions based on lecture summaries."},
89
+ {"role": "user", "content": user_query}
90
+ ]
 
 
91
  )
92
+ st.text(response["choices"][0]["message"]["content"])
93
+ else:
94
+ st.error("Please enter a question.")