shaheerawan3 commited on
Commit
6ecc602
·
verified ·
1 Parent(s): 76b501a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +209 -141
app.py CHANGED
@@ -1,181 +1,249 @@
1
  import streamlit as st
2
  from pathlib import Path
3
  import torch
4
- from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
5
- from diffusers import StableDiffusionPipeline
6
- from TTS.api import TTS
7
- import cv2
8
- import numpy as np
9
- from PIL import Image
10
  import tempfile
11
  import os
12
  from moviepy.editor import *
13
- import base64
 
 
14
 
15
- class VideoGenerator:
16
  def __init__(self):
17
- # Initialize text generation model
18
- self.text_model = AutoModelForCausalLM.from_pretrained(
19
- "facebook/opt-1.3b",
20
- torch_dtype=torch.float16,
21
- device_map="auto"
 
 
 
22
  )
23
- self.text_tokenizer = AutoTokenizer.from_pretrained("facebook/opt-1.3b")
24
-
25
- # Initialize image generation model
26
- self.image_generator = StableDiffusionPipeline.from_pretrained(
27
- "runwayml/stable-diffusion-v1-5",
28
- torch_dtype=torch.float16
29
- ).to("cuda")
30
-
31
- # Initialize TTS model
32
- self.tts = TTS(model_name="tts_models/en/ljspeech/tacotron2-DDC", progress_bar=False)
33
-
34
  # Create temp directory
35
  self.temp_dir = Path(tempfile.mkdtemp())
36
-
37
- def generate_script(self, prompt):
38
- """Generate detailed script with facts and scenes"""
39
- input_ids = self.text_tokenizer(
40
- f"Generate a detailed video script with facts about: {prompt}. Include scene descriptions.",
41
- return_tensors="pt"
42
- ).input_ids.to("cuda")
43
-
44
- outputs = self.text_model.generate(
45
- input_ids,
46
- max_length=500,
47
- temperature=0.7,
48
- num_return_sequences=1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  )
50
 
51
- script = self.text_tokenizer.decode(outputs[0], skip_special_tokens=True)
 
 
52
  return script
53
 
54
- def generate_scene_images(self, scene_descriptions):
55
- """Generate images for each scene using Stable Diffusion"""
56
- image_paths = []
57
- for i, desc in enumerate(scene_descriptions):
58
- image = self.image_generator(desc).images[0]
59
- path = self.temp_dir / f"scene_{i}.png"
60
- image.save(path)
61
- image_paths.append(path)
62
- return image_paths
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
- def generate_voiceover(self, script):
65
- """Generate voice narration using TTS"""
66
- audio_path = self.temp_dir / "voiceover.wav"
67
- self.tts.tts_to_file(script, file_path=str(audio_path))
 
68
  return audio_path
69
 
70
- def create_video(self, image_paths, audio_path, duration_per_image=5):
71
- """Combine images and audio into video"""
72
- clips = []
73
- for img_path in image_paths:
74
- clip = ImageClip(str(img_path)).set_duration(duration_per_image)
75
- clips.append(clip)
76
-
77
- video = concatenate_videoclips(clips)
 
 
 
 
 
 
 
 
 
 
 
 
78
  audio = AudioFileClip(str(audio_path))
79
 
80
- # Adjust video duration to match audio
81
- video = video.set_duration(audio.duration)
82
- final_video = video.set_audio(audio)
83
 
 
84
  output_path = self.temp_dir / "output_video.mp4"
85
- final_video.write_videofile(str(output_path), fps=24)
86
  return output_path
87
 
88
  def main():
89
- st.set_page_config(page_title="AI Video Generator", layout="wide")
90
- st.title("🎬 AI Text-to-Video Generator")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
  # Initialize session state
93
  if 'video_generator' not in st.session_state:
94
- st.session_state.video_generator = VideoGenerator()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
- # Input section
97
- st.header("Enter Your Topic")
 
 
 
 
 
 
98
  text_input = st.text_area(
99
- "What would you like to create a video about?",
100
  height=100,
101
- placeholder="Example: Explain the process of photosynthesis in plants..."
102
  )
103
 
104
- # Generation settings
105
- st.header("Video Settings")
106
- col1, col2 = st.columns(2)
107
- with col1:
108
- video_length = st.slider("Approximate video length (seconds)", 30, 300, 60)
109
- with col2:
110
- style = st.selectbox(
111
- "Video style",
112
- ["Educational", "Documentary", "Engaging", "Professional"]
113
- )
114
-
115
- # Generate button
116
- if st.button("🎥 Generate Video"):
117
  if text_input:
118
- with st.spinner("🤖 Generating your video..."):
119
- try:
120
- # Progress bar
121
- progress_bar = st.progress(0)
122
- progress_text = st.empty()
123
-
124
- # Generate script
125
- progress_text.text("Generating script...")
126
- script = st.session_state.video_generator.generate_script(text_input)
127
- progress_bar.progress(25)
128
-
129
- # Extract scene descriptions
130
- progress_text.text("Processing scenes...")
131
- scenes = [s.strip() for s in script.split("Scene:") if s.strip()]
132
- progress_bar.progress(40)
133
-
134
- # Generate images
135
- progress_text.text("Creating visuals...")
136
- image_paths = st.session_state.video_generator.generate_scene_images(scenes)
137
- progress_bar.progress(60)
138
-
139
- # Generate voiceover
140
- progress_text.text("Generating voiceover...")
141
- audio_path = st.session_state.video_generator.generate_voiceover(script)
142
- progress_bar.progress(80)
143
-
144
- # Create video
145
- progress_text.text("Composing final video...")
146
- video_path = st.session_state.video_generator.create_video(
147
- image_paths,
148
- audio_path,
149
- duration_per_image=video_length/len(scenes)
150
- )
151
- progress_bar.progress(100)
152
- progress_text.text("Video generation complete!")
153
-
154
- # Display results
155
- st.header("Generated Content")
156
-
157
- # Show script
158
- with st.expander("📝 Generated Script"):
159
- st.write(script)
160
-
161
- # Show video
162
- st.header("🎥 Your Video")
163
- video_file = open(str(video_path), 'rb')
164
- video_bytes = video_file.read()
165
- st.video(video_bytes)
166
 
167
  # Download button
168
- st.download_button(
169
- label="Download Video",
170
- data=video_bytes,
171
- file_name="generated_video.mp4",
172
- mime="video/mp4"
173
- )
174
-
175
- except Exception as e:
176
- st.error(f"An error occurred: {str(e)}")
 
 
 
 
 
177
  else:
178
- st.warning("Please enter some text to generate a video!")
179
 
180
  if __name__ == "__main__":
181
  main()
 
1
  import streamlit as st
2
  from pathlib import Path
3
  import torch
4
+ from transformers import pipeline
5
+ from PIL import Image, ImageDraw, ImageFont
 
 
 
 
6
  import tempfile
7
  import os
8
  from moviepy.editor import *
9
+ import numpy as np
10
+ from gtts import gTTS
11
+ import textwrap
12
 
13
+ class EnhancedVideoGenerator:
14
  def __init__(self):
15
+ # Use device agnostic setup
16
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
17
+
18
+ # Initialize text generation with a faster model
19
+ self.text_generator = pipeline(
20
+ 'text-generation',
21
+ model='distilgpt2', # Smaller, faster model
22
+ device=0 if self.device == "cuda" else -1
23
  )
24
+
 
 
 
 
 
 
 
 
 
 
25
  # Create temp directory
26
  self.temp_dir = Path(tempfile.mkdtemp())
27
+
28
+ # Store theme colors
29
+ self.themes = {
30
+ 'Professional': {
31
+ 'bg': (245, 245, 245),
32
+ 'text': (33, 33, 33),
33
+ 'accent': (0, 102, 204)
34
+ },
35
+ 'Creative': {
36
+ 'bg': (255, 240, 245),
37
+ 'text': (51, 51, 51),
38
+ 'accent': (255, 64, 129)
39
+ },
40
+ 'Educational': {
41
+ 'bg': (240, 249, 255),
42
+ 'text': (25, 25, 25),
43
+ 'accent': (0, 151, 167)
44
+ }
45
+ }
46
+
47
+ @st.cache_data
48
+ def generate_script(self, prompt, style, length):
49
+ """Generate engaging script based on style and length"""
50
+ style_prompts = {
51
+ 'Professional': "Write a clear, professional script about:",
52
+ 'Creative': "Write an engaging, creative script about:",
53
+ 'Educational': "Write an informative educational script about:"
54
+ }
55
+
56
+ max_length = int(length * 2.5) # Approximate words needed for duration
57
+
58
+ output = self.text_generator(
59
+ f"{style_prompts[style]} {prompt}. Keep it concise and engaging.",
60
+ max_length=max_length,
61
+ num_return_sequences=1,
62
+ temperature=0.7
63
  )
64
 
65
+ script = output[0]['generated_text']
66
+ # Clean up the generated text
67
+ script = script.replace(style_prompts[style], '').strip()
68
  return script
69
 
70
+ def create_styled_frame(self, text, theme, frame_number, total_frames):
71
+ """Create a visually appealing frame with text and progress bar"""
72
+ # Create base image
73
+ img = Image.new('RGB', (1280, 720), color=theme['bg'])
74
+ draw = ImageDraw.Draw(img)
75
+
76
+ # Wrap text for better presentation
77
+ wrapped_text = textwrap.fill(text, width=50)
78
+
79
+ # Add text
80
+ font_size = 40
81
+ try:
82
+ font = ImageFont.truetype("arial.ttf", font_size)
83
+ except:
84
+ font = ImageFont.load_default()
85
+
86
+ # Calculate text position for center alignment
87
+ text_bbox = draw.textbbox((0, 0), wrapped_text, font=font)
88
+ text_width = text_bbox[2] - text_bbox[0]
89
+ text_height = text_bbox[3] - text_bbox[1]
90
+ text_x = (1280 - text_width) // 2
91
+ text_y = (720 - text_height) // 2
92
+
93
+ # Draw text with subtle shadow for depth
94
+ draw.text((text_x+2, text_y+2), wrapped_text, fill=(0,0,0,128), font=font)
95
+ draw.text((text_x, text_y), wrapped_text, fill=theme['text'], font=font)
96
+
97
+ # Add progress bar
98
+ progress = frame_number / total_frames
99
+ bar_width = int(1000 * progress)
100
+ draw.rectangle([140, 650, 1140, 660], fill=(200,200,200))
101
+ draw.rectangle([140, 650, 140+bar_width, 660], fill=theme['accent'])
102
+
103
+ return np.array(img)
104
 
105
+ def generate_voiceover(self, script, lang='en'):
106
+ """Generate voice narration using gTTS"""
107
+ audio_path = self.temp_dir / "voiceover.mp3"
108
+ tts = gTTS(text=script, lang=lang, slow=False)
109
+ tts.save(str(audio_path))
110
  return audio_path
111
 
112
+ def create_video(self, script, theme, duration=30):
113
+ """Create video with animated text and voiceover"""
114
+ # Generate frames
115
+ fps = 24
116
+ total_frames = duration * fps
117
+
118
+ def make_frame(t):
119
+ frame_number = int(t * fps)
120
+ return self.create_styled_frame(
121
+ script,
122
+ self.themes[theme],
123
+ frame_number,
124
+ total_frames
125
+ )
126
+
127
+ # Create video clip
128
+ clip = VideoClip(make_frame, duration=duration)
129
+
130
+ # Generate and add voiceover
131
+ audio_path = self.generate_voiceover(script)
132
  audio = AudioFileClip(str(audio_path))
133
 
134
+ # Combine video and audio
135
+ final_clip = clip.set_audio(audio)
 
136
 
137
+ # Save video
138
  output_path = self.temp_dir / "output_video.mp4"
139
+ final_clip.write_videofile(str(output_path), fps=fps, codec='libx264')
140
  return output_path
141
 
142
  def main():
143
+ st.set_page_config(
144
+ page_title=" Smart Video Generator",
145
+ layout="wide",
146
+ initial_sidebar_state="expanded"
147
+ )
148
+
149
+ # Custom CSS for better UI
150
+ st.markdown("""
151
+ <style>
152
+ .stButton>button {
153
+ width: 100%;
154
+ height: 3em;
155
+ margin-top: 2em;
156
+ }
157
+ .stProgress .st-bo {
158
+ height: 20px;
159
+ }
160
+ </style>
161
+ """, unsafe_allow_html=True)
162
 
163
  # Initialize session state
164
  if 'video_generator' not in st.session_state:
165
+ with st.spinner("🚀 Initializing... (just a moment)"):
166
+ st.session_state.video_generator = EnhancedVideoGenerator()
167
+
168
+ # Sidebar for settings
169
+ with st.sidebar:
170
+ st.title("🎮 Video Settings")
171
+ theme = st.selectbox(
172
+ "Choose Theme",
173
+ ["Professional", "Creative", "Educational"],
174
+ help="Select the style for your video"
175
+ )
176
+
177
+ duration = st.slider(
178
+ "Video Duration (seconds)",
179
+ min_value=15,
180
+ max_value=90,
181
+ value=30,
182
+ step=15,
183
+ help="Choose the length of your video"
184
+ )
185
 
186
+ # Main content
187
+ st.title(" Smart Video Generator")
188
+ st.markdown("""
189
+ Transform your ideas into engaging videos with AI-powered content generation.
190
+ Just enter your topic below! 🎥
191
+ """)
192
+
193
+ # Input section with example
194
  text_input = st.text_area(
195
+ "What's your video about?",
196
  height=100,
197
+ placeholder="Example: Explain how rainbows form in the sky..."
198
  )
199
 
200
+ # Generate button with loading animation
201
+ if st.button("🎬 Generate Video", use_container_width=True):
 
 
 
 
 
 
 
 
 
 
 
202
  if text_input:
203
+ try:
204
+ progress_bar = st.progress(0)
205
+ status_text = st.empty()
206
+
207
+ # Generate script
208
+ status_text.text("✍️ Creating engaging script...")
209
+ script = st.session_state.video_generator.generate_script(
210
+ text_input, theme, duration
211
+ )
212
+ progress_bar.progress(30)
213
+
214
+ # Create video
215
+ status_text.text("🎨 Crafting visual elements...")
216
+ progress_bar.progress(60)
217
+
218
+ video_path = st.session_state.video_generator.create_video(
219
+ script, theme, duration
220
+ )
221
+ progress_bar.progress(100)
222
+ status_text.text("✨ Done! Your video is ready!")
223
+
224
+ # Display results in tabs
225
+ tab1, tab2 = st.tabs(["📽️ Video", "📝 Script"])
226
+
227
+ with tab1:
228
+ st.video(str(video_path))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
 
230
  # Download button
231
+ with open(str(video_path), 'rb') as f:
232
+ st.download_button(
233
+ "⬇️ Download Video",
234
+ f,
235
+ file_name="generated_video.mp4",
236
+ mime="video/mp4"
237
+ )
238
+
239
+ with tab2:
240
+ st.markdown("### Generated Script")
241
+ st.write(script)
242
+
243
+ except Exception as e:
244
+ st.error(f"💥 Oops! Something went wrong: {str(e)}")
245
  else:
246
+ st.warning("🎯 Please enter a topic to generate a video!")
247
 
248
  if __name__ == "__main__":
249
  main()