import os import json import urllib.request from PIL import Image from gtts import gTTS import cv2 import moviepy.editor as mp import logging from hercai import Hercai import uuid import time import gradio as gr from typing import Tuple, List # Enhanced logging configuration log_dir = os.getenv('LOG_DIRECTORY', './') LOGGER_FILE_PATH = os.path.join(str(log_dir), 'utils.log') logging.basicConfig( filename=LOGGER_FILE_PATH, filemode='a', format='[%(asctime)s] [%(levelname)s] [%(filename)s] [%(lineno)s:%(funcName)s()] %(message)s', datefmt='%Y-%b-%d %H:%M:%S', level=logging.INFO, handlers=[ logging.FileHandler(LOGGER_FILE_PATH), logging.StreamHandler() ] ) LOGGER = logging.getLogger(__name__) class Text2Video: def __init__(self) -> None: """Initialize the Text2Video class.""" self.herc = Hercai() LOGGER.info("Initialized Text2Video with Hercai API") def get_image(self, img_prompt: str) -> str: """Generate an image based on the provided text prompt.""" try: # Enhanced prompt engineering similar to DALL-E 3 enhanced_prompt = ( f"Create a high-quality comic panel: {img_prompt}. " "Style: Professional comic book illustration, " "vivid colors, clear composition, dramatic lighting. " "Include text as comic-style captions. " "Resolution: High detail, 1792x1024 aspect ratio. " "Quality: Professional grade comic art." ) result = self.herc.draw_image( model="simurg", # Using Hercai's best model prompt=enhanced_prompt, negative_prompt="blurry, low quality, poorly drawn, distorted" ) LOGGER.info(f"Successfully generated image for prompt: {img_prompt[:50]}...") return result["url"] except Exception as e: LOGGER.error(f"Error generating image: {e}") raise def download_img_from_url(self, image_url: str, image_path: str) -> str: """Download and process image from URL.""" try: urllib.request.urlretrieve(image_url, image_path) # Image processing for consistent quality img = Image.open(image_path) target_size = (1792, 1024) # Matching DALL-E 3 size img = img.resize(target_size, Image.Resampling.LANCZOS) img.save(image_path, quality=95) LOGGER.info(f"Successfully downloaded and processed image: {image_path}") return image_path except Exception as e: LOGGER.error(f"Error downloading image: {e}") raise def create_video_from_images_and_audio(self, image_files: list, audio_files: list, output_path: str) -> None: """Create video with enhanced quality settings.""" try: if len(image_files) != len(audio_files): raise ValueError("Number of images doesn't match number of audio files") video_clips = [] for image_file, audio_file in zip(image_files, audio_files): audio_clip = mp.AudioFileClip(audio_file) video_clip = mp.ImageClip(image_file).set_duration(audio_clip.duration) video_clip = video_clip.set_audio(audio_clip) video_clips.append(video_clip) final_clip = mp.concatenate_videoclips(video_clips) # Enhanced video quality settings final_clip.write_videofile( output_path, codec='libx264', fps=24, audio_codec='aac', audio_bitrate='192k', preset='medium', threads=4 ) LOGGER.info("Video created successfully") except Exception as e: LOGGER.error(f"Error creating video: {e}") raise # [Previous methods remain the same] def gradio_interface(self): """Create enhanced Gradio interface.""" with gr.Blocks(theme='abidlabs/dracula_revamped') as demo: gr.HTML("""
Create engaging comic-style videos from your stories