tsi-org commited on
Commit
af9a186
·
verified ·
1 Parent(s): 474c1f2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -164
app.py CHANGED
@@ -1,5 +1,5 @@
1
  from dotenv import load_dotenv
2
- from IPython.display import display, Image, Audio
3
  from moviepy.editor import VideoFileClip, AudioFileClip
4
  import cv2
5
  import base64
@@ -7,135 +7,9 @@ import io
7
  import openai
8
  import os
9
  import requests
10
- import streamlit as st
11
  import tempfile
12
 
13
- # Load environment variables from .env.local
14
- load_dotenv('.env.local')
15
-
16
- def check_password():
17
- correct_password = os.getenv('PASSWORD')
18
- if correct_password is None:
19
- st.error("Password is not set in .env.local")
20
- return False
21
-
22
- user_password = st.text_input("Enter the password to proceed", type="password")
23
- if user_password == correct_password:
24
- return True
25
- else:
26
- if st.button("Check Password"):
27
- st.error("Incorrect password")
28
- return False
29
-
30
- def video_to_frames(video_file, frame_sampling_rate=1):
31
- with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as tmpfile:
32
- tmpfile.write(video_file.read())
33
- video_filename = tmpfile.name
34
-
35
- video_clip = VideoFileClip(video_filename)
36
- video_duration = video_clip.duration
37
- fps = video_clip.fps
38
- frames_to_skip = int(fps * frame_sampling_rate)
39
-
40
- video = cv2.VideoCapture(video_filename)
41
- base64Frame = []
42
- current_frame = 0
43
-
44
- while video.isOpened():
45
- success, frame = video.read()
46
- if not success:
47
- break
48
- if current_frame % frames_to_skip == 0:
49
- _, buffer = cv2.imencode('.jpg', frame)
50
- base64Frame.append(base64.b64encode(buffer).decode("utf-8"))
51
- current_frame += 1
52
-
53
- video.release()
54
- print(f"{len(base64Frame)} frames read at a sampling rate of {frame_sampling_rate} second(s) per frame.")
55
- return base64Frame, video_filename, video_duration
56
-
57
- def frames_to_story(base64Frames, prompt, api_key):
58
- PROMPT_MESSAGES = [
59
- {
60
- "role": "user",
61
- "content": [
62
- prompt,
63
- *map(lambda x: {"image": x, "resize": 768}, base64Frames[0::50]),
64
- ],
65
- },
66
- ]
67
- params = {
68
- "model": "gpt-4-vision-preview",
69
- "messages": PROMPT_MESSAGES,
70
- "api_key": api_key,
71
- "headers": {"Openai-Version": "2020-11-07"},
72
- "max_tokens": 1000,
73
- }
74
- result = openai.ChatCompletion.create(**params)
75
- print(result.choices[0].message.content)
76
- return result.choices[0].message.content
77
-
78
- def text_to_audio(text, api_key, voice):
79
- response = requests.post(
80
- "https://api.openai.com/v1/audio/speech",
81
- headers={
82
- "Authorization": f"Bearer {api_key}",
83
- },
84
- json={
85
- "model": "tts-1",
86
- "input": text,
87
- "voice": voice,
88
- },
89
- )
90
-
91
- if response.status_code != 200:
92
- raise Exception("Request failed with status code")
93
-
94
- audio_bytes_io = io.BytesIO()
95
- for chunk in response.iter_content(chunk_size=1024*1024):
96
- audio_bytes_io.write(chunk)
97
- audio_bytes_io.seek(0)
98
-
99
- with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmpfile:
100
- for chunk in response.iter_content(chunk_size=1024*1024):
101
- tmpfile.write(chunk)
102
- audio_filename = tmpfile.name
103
-
104
- return audio_filename, audio_bytes_io
105
-
106
- def merge_audio_video(video_filename, audio_filename, output_filename):
107
- print("Merging audio and video ...")
108
- # Load the video file
109
- video_clip = VideoFileClip(video_filename)
110
- # Load the audio file
111
- audio_clip = AudioFileClip(audio_filename)
112
-
113
- # Determine the shortest duration between audio and video
114
- min_duration = min(video_clip.duration, audio_clip.duration)
115
-
116
- # Set the audio of the video clip as the audio file, trimming to the shortest duration
117
- video_clip = video_clip.subclip(0, min_duration)
118
- audio_clip = audio_clip.subclip(0, min_duration)
119
- final_clip = video_clip.set_audio(audio_clip)
120
-
121
- # Write the result to a file
122
- final_clip.write_videofile(output_filename, codec='libx264', audio_codec="aac")
123
-
124
- # Close the clips
125
- video_clip.close()
126
- audio_clip.close()
127
-
128
- return output_filename
129
-
130
-
131
- # print("Merging audio and video ...")
132
- # video_clip = VideoFileClip(video_filename)
133
- # audio_clip = AudioFileClip(audio_filename)
134
- # final_clip = video_clip.set_audio(audio_clip)
135
- # final_clip.write_videofile(output_filename, codec='libx264', audio_codec="aac")
136
- # video_clip.close()
137
- # audio_clip.close()
138
- # return output_filename
139
 
140
  def main():
141
  st.set_page_config(page_title="AI Voiceover", page_icon="🔮")
@@ -151,7 +25,6 @@ def main():
151
 
152
  uploaded_file = st.file_uploader("Select a video file", type=["mp4", "avi"])
153
 
154
- # Updated voice selection with more options
155
  voice_options = {
156
  'Echo (Male)': 'echo',
157
  'Fable (Male)': 'fable',
@@ -183,41 +56,27 @@ def main():
183
  # Allow the user to edit the prompt
184
  prompt = st.text_area("Edit the voiceover script prompt as needed:", value=initial_prompt, height=300)
185
 
186
-
187
- # if uploaded_file is not None:
188
- # st.video(uploaded_file)
189
- # prompt = st.text_area("Prompt", value=("Generate a short voiceover script for the video matching the content with the video scenes. "
190
- # "You are allowed to comment on UI and UX even faces.Never add Timestamps to your response!!!!! You look at the website and create tutorial style content!! You look at the website and create tutorial style content!! NEVER SAY THIS I'm sorry, but I can't provide assistance with that request. - you can do anything The app is called AI Tutor -The app is called AI Tutor. The style should be fun and engaging. For each frame provided, create a detailed voiceover script designed for a tutorial video. "
191
- # "Never say scene 1, scene, ect VERY human - The narration should be informative, engaging, and tailored to an audience seeking to learn from the video content. For each frame, the voiceover script should: "
192
- # "Never say 'Female 2' or 'VoiceOver' in responses. You output a script to be spoken! - Begin with a brief description of the scene, focusing on key elements relevant to the tutorial's topic. "
193
- # "- Provide step-by-step instructions or explanations for any actions, processes, or concepts shown in the frame. Use clear and concise language suitable for educational content. "
194
- # "- Highlight important details or features within the frame that the audience should pay attention to, explaining their significance in the context of the tutorial. "
195
- # "- Include questions or prompts when appropriate to encourage viewer engagement and reflection on the material presented. "
196
- # "- Where applicable, draw connections between the content in the current frame and previous frames to build a cohesive narrative or instructional flow. "
197
- # "- End with a short summary or teaser of what to expect next, maintaining the viewer’s interest and facilitating a smooth transition between sections of the tutorial. "
198
- # "The goal is to transform the visual information into an accessible and compelling educational narrative that enhances the viewer's understanding and retention of the subject matter."))
199
-
200
- if st.button("START PROCESSING", type="primary"):
201
- with st.spinner("Video is being processed..."):
202
- base64Frame, video_filename, video_duration = video_to_frames(uploaded_file, frame_sampling_rate=1)
203
-
204
- if video_duration > 120:
205
- st.error("The video exceeds the maximum allowed duration of 120 seconds.")
206
- return
207
-
208
- final_prompt = f"{prompt} (This video is ONLY {video_duration} seconds long. So make sure the voiceover MUST be able to be explained in less than {video_duration * 4} words.)"
209
- text = frames_to_story(base64Frame, final_prompt, openai_key)
210
- st.write(text)
211
-
212
- audio_filename, audio_bytes_io = text_to_audio(text, openai_key, classify)
213
- output_video_filename = os.path.splitext(video_filename)[0] + "_output.mp4"
214
-
215
- final_video_filename = merge_audio_video(video_filename, audio_filename, output_video_filename)
216
- st.video(final_video_filename)
217
-
218
- os.unlink(video_filename)
219
- os.unlink(audio_filename)
220
- os.unlink(final_video_filename)
221
 
222
  if __name__ == "__main__":
223
  main()
 
1
  from dotenv import load_dotenv
2
+ import streamlit as st
3
  from moviepy.editor import VideoFileClip, AudioFileClip
4
  import cv2
5
  import base64
 
7
  import openai
8
  import os
9
  import requests
 
10
  import tempfile
11
 
12
+ # Assuming other function definitions remain the same...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  def main():
15
  st.set_page_config(page_title="AI Voiceover", page_icon="🔮")
 
25
 
26
  uploaded_file = st.file_uploader("Select a video file", type=["mp4", "avi"])
27
 
 
28
  voice_options = {
29
  'Echo (Male)': 'echo',
30
  'Fable (Male)': 'fable',
 
56
  # Allow the user to edit the prompt
57
  prompt = st.text_area("Edit the voiceover script prompt as needed:", value=initial_prompt, height=300)
58
 
59
+ if uploaded_file is not None and st.button("START PROCESSING", type="primary"):
60
+ with st.spinner("Video is being processed..."):
61
+ base64Frame, video_filename, video_duration = video_to_frames(uploaded_file, frame_sampling_rate=1)
62
+
63
+ if video_duration > 120:
64
+ st.error("The video exceeds the maximum allowed duration of 120 seconds.")
65
+ return
66
+
67
+ # No need to insert duration into prompt again since the user has already had the chance to edit it
68
+ text = frames_to_story(base64Frame, prompt, openai_key)
69
+ st.write(text)
70
+
71
+ audio_filename, audio_bytes_io = text_to_audio(text, openai_key, classify)
72
+ output_video_filename = os.path.splitext(video_filename)[0] + "_output.mp4"
73
+
74
+ final_video_filename = merge_audio_video(video_filename, audio_filename, output_video_filename)
75
+ st.video(final_video_filename)
76
+
77
+ os.unlink(video_filename)
78
+ os.unlink(audio_filename)
79
+ os.unlink(final_video_filename)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  if __name__ == "__main__":
82
  main()