Ritvik19 commited on
Commit
abadf6e
·
verified ·
1 Parent(s): b4fb7d8

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +248 -0
  2. requirements.txt +9 -0
app.py ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import base64
4
+ import os
5
+ from moviepy.editor import VideoFileClip
6
+ from pytube import YouTube
7
+ from youtube_transcript_api import YouTubeTranscriptApi
8
+ from youtube_transcript_api._errors import CouldNotRetrieveTranscript
9
+ import whisper
10
+ import ffmpeg
11
+ import re
12
+ import tempfile
13
+ import openai
14
+
15
+ st.set_page_config(layout="wide", initial_sidebar_state="collapsed")
16
+
17
+ PROMPT = """Act as the author and provide a comprehensive detailed article in the same language as the transcript
18
+ in markdown format that has a H1 main title(example "# <this is a title> ") and broken down into H2 subtitles (example "## <this is a title> ") for the following transcript
19
+ You must follow the rules:
20
+
21
+ - Write the article in markdown format
22
+ - Create a main title for the article as markdown H1 and break the article into subtitles where each subtitle is markdown H2
23
+ - Article must be in the same language as the transcript
24
+ - summary should be informative and act as a replacement for the original transcript to the point that the user doesn't have to go back to read the transcript
25
+ - Summary should not mention the author or speaker at all should act as your independent writing without referencing the original transcript or speaker.
26
+ - You can use bullet points within the article
27
+ Transcript:
28
+ {} \n\n Article:"""
29
+
30
+
31
+ @st.cache_resource()
32
+ def load_whisper(model):
33
+ return whisper.load_model(model)
34
+
35
+
36
+ @st.cache_data
37
+ def download_video(url):
38
+ if "youtube" in url or "youtu.be" in url:
39
+ yt = YouTube(url)
40
+ video = yt.streams.get_highest_resolution()
41
+ filename = video.download()
42
+ else:
43
+ response = requests.get(url, stream=True)
44
+ filename = url.split("/")[-1]
45
+ with open(filename, "wb") as file:
46
+ for chunk in response.iter_content(chunk_size=1024):
47
+ if chunk:
48
+ file.write(chunk)
49
+ return filename
50
+
51
+
52
+ @st.cache_data
53
+ def convert_to_audio(video_filename):
54
+ video = VideoFileClip(video_filename)
55
+ audio_filename = video_filename.replace(".mp4", ".mp3")
56
+ audio = video.audio
57
+ audio.write_audiofile(audio_filename, codec="mp3")
58
+ return audio_filename
59
+
60
+
61
+ @st.cache_data
62
+ def summarise(prompt, model="gpt-3.5-turbo"):
63
+ if openai.api_key is None:
64
+ return "No OpenAI API Key provided."
65
+ messages = [{"role": "user", "content": prompt}]
66
+ response = openai.ChatCompletion.create(
67
+ model=model,
68
+ messages=messages,
69
+ temperature=0,
70
+ )
71
+ return response.choices[0].message["content"]
72
+
73
+
74
+ def delete_files(video_filename, audio_filename):
75
+ delete_file(video_filename)
76
+ delete_file(audio_filename)
77
+
78
+
79
+ def delete_file(filename):
80
+ if os.path.exists(filename):
81
+ os.remove(filename)
82
+ st.info(f"File '{os.path.basename(filename)}' deleted from the server.")
83
+
84
+
85
+ @st.cache_data
86
+ def transcribe_whisper(_model, audio_filepath):
87
+ return _model.transcribe(audio_filepath)["text"]
88
+
89
+
90
+ def get_media_download_link(media_type, file_path):
91
+ with open(file_path, "rb") as file:
92
+ contents = file.read()
93
+ encoded = base64.b64encode(contents).decode("utf-8")
94
+ media_href = f"data:file/{media_type};base64,{encoded}"
95
+ st.markdown(
96
+ f'<a href="{media_href}" download="{os.path.basename(file_path)}">Download {os.path.basename(file_path)}</a>',
97
+ unsafe_allow_html=True,
98
+ )
99
+
100
+
101
+ @st.cache_data
102
+ def generate_summaries(_summarizer, text, min_length=50, max_length=500):
103
+ paragraphs = text.split("\n\n")
104
+ summaries = []
105
+ for paragraph in paragraphs:
106
+ summary = _summarizer(
107
+ paragraph, max_length=max_length, min_length=min_length, do_sample=False
108
+ )
109
+ summaries.append(summary[0]["summary_text"].strip())
110
+ return "\n\n".join(summaries)
111
+
112
+
113
+ def main():
114
+ st.title("VidScripter")
115
+ st.write("#### A One Stop Solution to Video Transcription")
116
+ c1, c2 = st.columns(2)
117
+ c1.write(
118
+ """
119
+ - Enter the video URL in the text input box.
120
+ - Click the **Fetch** button to fetch the video.
121
+ - Once the video is fetched, you can perform the following actions:
122
+ - Fetch transcript from YouTube API (if available) by clicking the **Fetch Transcript** button.
123
+ - Transcribe the video using the Whisper model by clicking the **Transcribe (Whisper)** button.
124
+ - The transcript will be displayed in a text area below.
125
+ - If you have an OpenAI API Key, you will be able to generate a summary of the transcript by ChatGPT.
126
+ - The summary will be displayed in a text area below.
127
+ - You can download the video, audio, transcript or summary by clicking the respective download buttons.
128
+ """
129
+ )
130
+
131
+ whisper_model = load_whisper("base")
132
+
133
+ url = c2.text_input("Enter the video URL")
134
+ open_ai_key = c2.text_input("Enter your OpenAI API Key")
135
+ if open_ai_key != "":
136
+ openai.api_key = open_ai_key
137
+ fetch_button = c2.button("Fetch")
138
+ st.session_state.setdefault("load_state", False)
139
+
140
+ if fetch_button or st.session_state.load_state:
141
+ st.session_state.load_state = True
142
+
143
+ if url:
144
+ process_video(url, whisper_model)
145
+
146
+
147
+ def process_video(url, whisper_model):
148
+ yt = YouTube(url)
149
+ video_id = yt.video_id
150
+ try:
151
+ video_filename = download_video(url)
152
+ st.success("Video fetched successfully")
153
+ except Exception:
154
+ video_filename = None
155
+ st.warning("Video could not be fetched")
156
+
157
+ try:
158
+ audio_filename = (
159
+ convert_to_audio(video_filename) if video_filename is not None else None
160
+ )
161
+ if video_filename is not None:
162
+ st.success("Audio converted successfully")
163
+ else:
164
+ st.info("No Video to convert into Audio")
165
+ except Exception:
166
+ audio_filename = None
167
+ st.warning("Audio coud not be converted")
168
+
169
+ text_filename = (
170
+ os.path.basename(video_filename).replace(".mp4", ".txt")
171
+ if video_filename is not None
172
+ else "transcript.txt"
173
+ )
174
+ emp = st.empty()
175
+
176
+ col1, col2, col3, col4 = st.columns(4)
177
+
178
+ if "youtube" in url or "youtu.be" in url:
179
+ process_youtube_video(video_id, col3, emp, text_filename)
180
+
181
+ process_whisper_transcript(whisper_model, audio_filename, col4, text_filename)
182
+
183
+ with col1:
184
+ if video_filename is not None and st.button("Download Video"):
185
+ with st.spinner("Encoding Video"):
186
+ get_media_download_link("video", video_filename)
187
+
188
+ with col2:
189
+ if audio_filename is not None and st.button("Download Audio"):
190
+ with st.spinner("Encoding Audio"):
191
+ get_media_download_link("audio", audio_filename)
192
+
193
+
194
+ def process_youtube_video(video_id, col, emp, text_filename):
195
+ try:
196
+ transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
197
+ transcripts = [transcript for transcript in transcript_list]
198
+
199
+ if transcripts:
200
+ transcript_options = {
201
+ f"{transcript.language} ({transcript.language_code})": transcript
202
+ for transcript in transcripts
203
+ }
204
+ transcript_option = emp.selectbox(
205
+ "Select a transcript", list(transcript_options.keys())
206
+ )
207
+ selected_transcript = transcript_options[transcript_option]
208
+
209
+ st.session_state.setdefault("api_transcript", False)
210
+ if col.button("Fetch Transcript") or st.session_state.api_transcript:
211
+ st.session_state.api_transcript = True
212
+ transcript_text = selected_transcript.fetch()
213
+ transcript_text = "\n".join(
214
+ [re.sub("\s+", " ", chunk["text"]) for chunk in transcript_text]
215
+ )
216
+ c1, c2 = st.columns(2)
217
+ with c1:
218
+ modified_text = st.text_area(
219
+ "Transcript", transcript_text, height=500
220
+ )
221
+ st.download_button("Download Transcript", modified_text, text_filename)
222
+ with c2:
223
+ openai_summarization = summarise(
224
+ PROMPT.format(modified_text)
225
+ )
226
+ summarized_text = st.text_area(
227
+ "Summarized Transcript", openai_summarization, height=500
228
+ )
229
+ st.download_button("Download Summary", summarized_text, text_filename)
230
+
231
+ except CouldNotRetrieveTranscript:
232
+ emp.warning("Could Not Retrieve API Transcripts for this video.")
233
+ except Exception as e:
234
+ emp.warning(f"Error Fetching API Transcripts for this video. {e}")
235
+
236
+
237
+ def process_whisper_transcript(whisper_model, audio_filename, col, text_filename):
238
+ if audio_filename is not None:
239
+ st.session_state.setdefault("whisper_transcript", False)
240
+ if col.button("Transcribe (Whisper)") or st.session_state.whisper_transcript:
241
+ st.session_state.whisper_transcript = True
242
+ whisper_text = transcribe_whisper(whisper_model, audio_filename)
243
+ modified_text = st.text_area("Transcript", whisper_text, height=500)
244
+ st.download_button("Download", modified_text, text_filename)
245
+
246
+
247
+ if __name__ == "__main__":
248
+ main()
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ SpeechRecognition
2
+ ffmpeg-python
3
+ pydub
4
+ pytube
5
+ youtube-transcript-api
6
+ openai-whisper
7
+ moviepy
8
+ transformers
9
+ openai==0.28