shaheerawan3 commited on
Commit
0093091
·
verified ·
1 Parent(s): 8f90878

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -59
app.py CHANGED
@@ -284,40 +284,47 @@ class EnhancedVideoGenerator:
284
  self.logger.error(f"Voice-over generation failed: {str(e)}")
285
  return AudioFileClip(duration=len(script.split()) * 0.3)
286
 
287
- def create_video(
288
- self,
289
- script: str,
290
- style: str,
291
- duration: int,
292
- output_path: str
293
- ) -> str:
294
- """Create full video with all enhanced features"""
295
- try:
296
- # Generate visual assets
297
- assets = self.generate_visual_assets(script, style)
298
-
299
- # Generate voice-over
300
- audio = self.generate_voice_over(script)
301
-
302
- # Create frames with visual assets
303
- frames = []
304
- fps = 30
305
- total_frames = int(duration * fps)
306
-
307
- with ThreadPoolExecutor() as executor:
308
- frame_futures = []
 
 
 
 
 
 
 
 
 
309
 
310
- for i in range(total_frames):
311
- # Calculate current text segment
312
  progress = i / total_frames
313
  text_index = int(progress * len(script.split()))
314
  current_text = " ".join(script.split()[:text_index + 1])
315
 
316
- # Get appropriate background
317
- asset_index = int(progress * len(assets))
318
  current_asset = assets[asset_index] if assets else None
319
 
320
- # Submit frame creation to thread pool
321
  future = executor.submit(
322
  self.create_enhanced_frame,
323
  current_text,
@@ -328,38 +335,58 @@ class EnhancedVideoGenerator:
328
  )
329
  frame_futures.append(future)
330
 
331
- # Collect frames
332
- frames = [future.result() for future in frame_futures]
333
-
334
- # Create video clip
335
- video = ImageSequenceClip(frames, fps=fps)
336
-
337
- # Add voice-over
338
- video = video.set_audio(audio)
339
-
340
- # Add background music (if available)
341
- try:
342
- music = AudioFileClip("assets/music/background.mp3")
343
- music = music.volumex(0.1).loop(duration=video.duration)
344
- video = video.set_audio(CompositeAudioClip([video.audio, music]))
345
- except Exception as e:
346
- self.logger.warning(f"Background music addition failed: {str(e)}")
347
-
348
- # Write final video
349
- video.write_videofile(
350
- output_path,
351
- fps=fps,
352
- codec='libx264',
353
- audio_codec='aac',
354
- threads=4,
355
- preset='medium'
356
- )
357
-
358
- return output_path
359
-
360
- except Exception as e:
361
- self.logger.error(f"Video creation failed: {str(e)}")
362
- raise
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
 
364
  @staticmethod
365
  def clean_text(text: str) -> str:
 
284
  self.logger.error(f"Voice-over generation failed: {str(e)}")
285
  return AudioFileClip(duration=len(script.split()) * 0.3)
286
 
287
+ def create_video(self, script: str, style: str, duration: int, output_path: str) -> str:
288
+ """Create full video with all enhanced features"""
289
+ try:
290
+ # Progress bar
291
+ progress_bar = st.progress(0)
292
+ status_text = st.empty()
293
+
294
+ # Generate visual assets (20%)
295
+ status_text.text("Generating visual assets...")
296
+ assets = self.generate_visual_assets(script, style)
297
+ progress_bar.progress(20)
298
+
299
+ # Generate voice-over (40%)
300
+ status_text.text("Creating voice-over...")
301
+ audio = self.generate_voice_over(script)
302
+ progress_bar.progress(40)
303
+
304
+ # Create frames
305
+ fps = 30
306
+ total_frames = int(duration * fps)
307
+ frames = []
308
+
309
+ # Use smaller batch size for better memory management
310
+ batch_size = 10
311
+ num_batches = (total_frames + batch_size - 1) // batch_size
312
+
313
+ with ThreadPoolExecutor(max_workers=4) as executor:
314
+ for batch in range(num_batches):
315
+ status_text.text(f"Generating frames: {batch*batch_size}/{total_frames}")
316
+ start_frame = batch * batch_size
317
+ end_frame = min((batch + 1) * batch_size, total_frames)
318
 
319
+ frame_futures = []
320
+ for i in range(start_frame, end_frame):
321
  progress = i / total_frames
322
  text_index = int(progress * len(script.split()))
323
  current_text = " ".join(script.split()[:text_index + 1])
324
 
325
+ asset_index = int(progress * len(assets)) if assets else 0
 
326
  current_asset = assets[asset_index] if assets else None
327
 
 
328
  future = executor.submit(
329
  self.create_enhanced_frame,
330
  current_text,
 
335
  )
336
  frame_futures.append(future)
337
 
338
+ batch_frames = [future.result() for future in frame_futures]
339
+ frames.extend(batch_frames)
340
+
341
+ progress = int(60 + (batch/num_batches) * 30)
342
+ progress_bar.progress(progress)
343
+
344
+ # Create video clip (90%)
345
+ status_text.text("Compiling video...")
346
+ video = ImageSequenceClip(frames, fps=fps)
347
+ video = video.set_audio(audio)
348
+ progress_bar.progress(90)
349
+
350
+ # Write final video (100%)
351
+ status_text.text("Saving video...")
352
+ video.write_videofile(
353
+ output_path,
354
+ fps=fps,
355
+ codec='libx264',
356
+ audio_codec='aac',
357
+ threads=4,
358
+ preset='ultrafast' # Faster encoding
359
+ )
360
+
361
+ progress_bar.progress(100)
362
+ status_text.text("Video generation complete!")
363
+ return output_path
364
+
365
+ except Exception as e:
366
+ self.logger.error(f"Video creation failed: {str(e)}")
367
+ raise
368
+
369
+ def generate_visual_assets(self, script: str, style: str) -> List[Dict]:
370
+ """Generate relevant visual assets based on script content"""
371
+ try:
372
+ # Simplified asset generation for faster processing
373
+ topics = self.extract_key_topics(script)[:3] # Limit to 3 topics
374
+
375
+ assets = []
376
+ for topic in topics:
377
+ # Create simple colored backgrounds instead of AI images
378
+ img = Image.new('RGB', (1920, 1080), self.themes[style]['bg'])
379
+ assets.append({
380
+ 'type': 'image',
381
+ 'data': img,
382
+ 'topic': topic
383
+ })
384
+
385
+ return assets
386
+
387
+ except Exception as e:
388
+ self.logger.error(f"Visual asset generation failed: {str(e)}")
389
+ return []
390
 
391
  @staticmethod
392
  def clean_text(text: str) -> str: