Mpavan45 commited on
Commit
746bd87
·
verified ·
1 Parent(s): 34cca99

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -156
app.py CHANGED
@@ -1,160 +1,84 @@
1
  import streamlit as st
2
  import whisper
3
- import tempfile
4
- import os
5
- import chromadb
6
- from pydub import AudioSegment
7
- from sentence_transformers import SentenceTransformer
8
- import numpy as np
9
  import pickle
10
-
11
- # 💡 Set Page Configuration
12
- st.set_page_config(page_title="Audio Subtitle Tool", layout="wide")
13
-
14
- # 🌐 Initialize ChromaDB
15
- db_client = chromadb.PersistentClient(path="./chroma_data")
16
- sub_db = db_client.get_or_create_collection(name="audio_subtitles")
17
-
18
- # ⚙️ Load Whisper Model
19
- @st.cache_resource()
20
- def load_transcriber():
21
- return whisper.load_model("base")
22
-
23
- transcriber = load_transcriber()
24
-
25
- # ⚙️ Load Sentence Transformer
26
- @st.cache_resource()
27
- def load_encoder():
28
- return SentenceTransformer("paraphrase-MiniLM-L6-v2")
29
-
30
- semantic_encoder = load_encoder()
31
-
32
- # 🔥 Load Subtitle Data from Pickle
33
- @st.cache_resource()
34
- def load_subtitle_store():
35
- with open("subtitle_data.pkl", "rb") as file:
36
- subtitle_store = pickle.load(file)
37
-
38
- # ⏱️ Format Time into SRT format
39
- def time_formatter(sec):
40
- hr = int(sec // 3600)
41
- mins = int((sec % 3600) // 60)
42
- secs = int(sec % 60)
43
- millis = int((sec % 1) * 1000)
44
- return f"{hr:02}:{mins:02}:{secs:02},{millis:03}"
45
-
46
- # 🎙️ Transcribe Audio and Store in ChromaDB
47
- @st.cache_resource()
48
- def process_audio(file_path):
49
- result = transcriber.transcribe(file_path, beam_size=1)
50
- segments = result['segments']
51
- srt_subtitles = []
52
- plain_text_subs = []
53
-
54
- for idx, seg in enumerate(segments):
55
- start = time_formatter(seg['start'])
56
- end = time_formatter(seg['end'])
57
- content = seg['text']
58
-
59
- # Create SRT format
60
- srt_subtitles.append(f"{idx + 1}\n{start} --> {end}\n{content}\n")
61
- plain_text_subs.append(content)
62
-
63
- # Store in ChromaDB
64
- sub_db.upsert(
65
- documents=[content],
66
- metadatas=[{"start_time": start, "end_time": end}],
67
- ids=[f"subtitle_{idx}"]
68
  )
69
-
70
- return "\n".join(srt_subtitles), " ".join(plain_text_subs)
71
-
72
- # 🔍 Subtitle Search Function
73
- def search_content(query):
74
- query_vec = semantic_encoder.encode(query).tolist()
75
- matches = sub_db.query(query_embeddings=[query_vec], n_results=5)
76
-
77
- if 'documents' in matches and matches['documents']:
78
- results = []
79
- for idx, doc in enumerate(matches['documents'][0]):
80
- meta = matches['metadatas'][0][idx]
81
- results.append(f"📌 {doc} (From: {meta['start_time']} → To: {meta['end_time']})")
82
- return results
83
- return []
84
-
85
- # 🔥 Sidebar Navigation
86
- st.sidebar.title("🎯 Navigation")
87
- page = st.sidebar.radio("Choose Action", ["Generate Subtitles", "Search Subtitles"])
88
-
89
- # 🎛️ Sidebar Styling
90
- st.sidebar.markdown(
91
- """
92
- <style>
93
- .sidebar .sidebar-content {
94
- background-color: #f0f0f5;
95
- color: #333;
96
- }
97
- </style>
98
- """,
99
- unsafe_allow_html=True
100
- )
101
-
102
- # 🎬 Header Section
103
- st.markdown(
104
- """
105
- <h1 style='text-align: center; color: #673AB7;'>🎤 Audio Subtitle Generator & Search</h1>
106
- <p style='text-align: center; font-size: 18px; color: #666;'>Generate subtitles from audio files and search through them.</p>
107
- """,
108
- unsafe_allow_html=True
109
- )
110
-
111
- # 🚀 Load Subtitle Data
112
- load_subtitle_store()
113
-
114
- # 🎵 File Upload Section
115
- st.markdown("### 🎧 Upload Your Audio File")
116
- audio_file = st.file_uploader("Supported formats: MP3, WAV", type=["mp3", "wav"])
117
-
118
- # 🎯 Page Logic
119
- if page == "Generate Subtitles":
120
- if audio_file:
121
- st.audio(audio_file, format='audio/mp3')
122
-
123
- with st.spinner("🔧 Processing audio... Please wait."):
124
- # Temporary file handling
125
- with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp_audio:
126
- if audio_file.name.endswith(".mp3"):
127
- audio = AudioSegment.from_mp3(audio_file)
128
- elif audio_file.name.endswith(".wav"):
129
- audio = AudioSegment.from_wav(audio_file)
130
- audio = audio.set_frame_rate(16000)
131
- audio.export(tmp_audio.name, format="wav")
132
-
133
- # Transcribe and store in ChromaDB
134
- subtitle_output, plain_output = process_audio(tmp_audio.name)
135
- st.success("✅ Transcription Completed!")
136
-
137
- # Display Subtitles
138
- st.markdown("### 📜 Generated Subtitles")
139
- st.text_area("Subtitles (SRT Format)", subtitle_output, height=300)
140
-
141
- # Download Options
142
- st.download_button("⬇️ Download SRT File", subtitle_output, file_name="subtitles.srt", mime="text/plain")
143
- st.download_button("⬇️ Download Plain Text", plain_output, file_name="subtitles.txt", mime="text/plain")
144
-
145
- os.remove(tmp_audio.name)
146
-
147
- elif page == "Search Subtitles":
148
- st.subheader("🔎 Search Subtitles")
149
- query_input = st.text_input("Enter text to search")
150
-
151
- if query_input:
152
- with st.spinner("🔍 Searching..."):
153
- search_matches = search_content(query_input)
154
-
155
- if search_matches:
156
- st.success("✅ Results Found:")
157
- for match in search_matches:
158
- st.write(match)
159
- else:
160
- st.warning("⚠️ No matching results. Try a different query.")
 
1
  import streamlit as st
2
  import whisper
3
+ import moviepy.editor as mp
4
+ import pandas as pd
 
 
 
 
5
  import pickle
6
+ import os
7
+ from chromadb.utils import embedding_functions
8
+ from chromadb import Client
9
+ from chromadb.config import Settings
10
+
11
+ def extract_audio(video_file):
12
+ """Extracts audio from uploaded video file."""
13
+ video = mp.VideoFileClip(video_file)
14
+ audio_path = "temp_audio.wav"
15
+ video.audio.write_audiofile(audio_path)
16
+ return audio_path
17
+
18
+ def transcribe_audio(audio_path):
19
+ """Transcribes audio to text using Whisper."""
20
+ model = whisper.load_model("base")
21
+ result = model.transcribe(audio_path)
22
+ return result['text']
23
+
24
+ def load_embeddings():
25
+ """Loads subtitle embeddings from pkl file."""
26
+ with open('subtitle_embeddings.pkl', 'rb') as f:
27
+ embeddings = pickle.load(f)
28
+ return embeddings
29
+
30
+ def save_to_chroma(embeddings):
31
+ """Stores embeddings in Chroma DB."""
32
+ client = Client(Settings())
33
+ collection = client.create_collection(name="subtitles")
34
+ for idx, row in embeddings.iterrows():
35
+ collection.add(
36
+ documents=[row['subtitle']],
37
+ ids=[str(idx)],
38
+ embeddings=[row['embedding']]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  )
40
+ return collection
41
+
42
+ def search_subtitles(query, collection):
43
+ """Searches for subtitles in Chroma DB."""
44
+ results = collection.query(query_texts=[query], n_results=5)
45
+ return results['documents']
46
+
47
+ def main():
48
+ st.set_page_config(page_title="Video Subtitle Generator", layout="wide")
49
+ st.title("🎥 Video Subtitle Generator")
50
+
51
+ with st.sidebar:
52
+ uploaded_file = st.file_uploader("Upload Video", type=["mp4", "mkv"])
53
+ query = st.text_input("Search Subtitles")
54
+ download_btn = st.button("Download Subtitles")
55
+
56
+ if uploaded_file:
57
+ with st.spinner("Extracting audio..."):
58
+ audio_path = extract_audio(uploaded_file.name)
59
+
60
+ with st.spinner("Generating subtitles..."):
61
+ subtitles = transcribe_audio(audio_path)
62
+ st.success("Subtitles Generated!")
63
+
64
+ # Display the video and subtitles
65
+ st.video(uploaded_file)
66
+ st.text_area("Generated Subtitles", subtitles, height=300)
67
+
68
+ # Load and search embeddings
69
+ embeddings = load_embeddings()
70
+ collection = save_to_chroma(embeddings)
71
+
72
+ if query:
73
+ results = search_subtitles(query, collection)
74
+ st.write("### Matching Subtitles:")
75
+ for sub in results:
76
+ st.write(f"- {sub}")
77
+
78
+ if download_btn:
79
+ with open("generated_subtitles.srt", "w") as f:
80
+ f.write(subtitles)
81
+ st.download_button("Download SRT", "generated_subtitles.srt")
82
+
83
+ if __name__ == '__main__':
84
+ main()