I am trying to make a would you rather generator, but I have some issues with the audio saving right now.

app.py:
# app copy.py

import os
import sys
from pathlib import Path

# Import functions from existing scripts
from text_generation import generate_would_you_rather
from image_generation import ComfyUIGenerator
from voice_generation import generate_tts
from moviepy.editor import AudioFileClip

# Import the video generator class
from video_generation import WouldYouRatherGenerator  # Ensure the file is named correctly

def debug_print(message):
    print(f"[DEBUG] {message}")

def parse_would_you_rather_text(file_path):
    """
    Parses the 'would_you_rather.txt' file to extract choices and image descriptions.
    Designed to handle minor deviations in formatting.
    
    Expected block structure for each pair:
    1.
    CHOICE: First choice description
    IMAGE: First image description
    VERSUS
    CHOICE: Second choice description
    IMAGE: Second image description
    """
    pairs = []
    with open(file_path, 'r', encoding='utf-8') as f:
        lines = [line.strip() for line in f if line.strip()]  # Remove empty lines

    i = 0
    total_lines = len(lines)
    pair_number = 1
    while i < total_lines:
        line = lines[i]
        if line.endswith('.'):
            debug_print(f"Parsing pair {pair_number} starting at line {i+1}")
            pair = {}
            j = i + 1  # Start parsing after the number line

            # Initialize flags to check if essential components are found
            choice1_found = False
            image1_found = False
            versus_found = False
            choice2_found = False
            image2_found = False

            while j < total_lines and not (lines[j].endswith('.') and lines[j].rstrip('.').isdigit()):
                current_line = lines[j].upper()
                if current_line.startswith('CHOICE:'):
                    if not choice1_found:
                        pair['option1'] = lines[j][len('CHOICE:'):].strip()
                        choice1_found = True
                        debug_print(f"Pair {pair_number} - Option 1: {pair['option1']}")
                    elif not choice2_found:
                        pair['option2'] = lines[j][len('CHOICE:'):].strip()
                        choice2_found = True
                        debug_print(f"Pair {pair_number} - Option 2: {pair['option2']}")
                elif current_line.startswith('IMAGE:'):
                    if choice1_found and not image1_found:
                        pair['image1_desc'] = lines[j][len('IMAGE:'):].strip()
                        image1_found = True
                        debug_print(f"Pair {pair_number} - Image 1: {pair['image1_desc']}")
                    elif choice2_found and not image2_found:
                        pair['image2_desc'] = lines[j][len('IMAGE:'):].strip()
                        image2_found = True
                        debug_print(f"Pair {pair_number} - Image 2: {pair['image2_desc']}")
                elif current_line == 'VERSUS':
                    versus_found = True
                    debug_print(f"Pair {pair_number} - Versus found")
                else:
                    debug_print(f"Pair {pair_number} - Unrecognized line: '{lines[j]}'")
                j += 1

            # Validate if all components are found
            if choice1_found and image1_found and versus_found and choice2_found and image2_found:
                pairs.append(pair)
                debug_print(f"Successfully parsed pair {pair_number}")
                pair_number += 1
            else:
                missing = []
                if not choice1_found:
                    missing.append("Option 1 Choice")
                if not image1_found:
                    missing.append("Option 1 Image")
                if not versus_found:
                    missing.append("'VERSUS'")
                if not choice2_found:
                    missing.append("Option 2 Choice")
                if not image2_found:
                    missing.append("Option 2 Image")
                debug_print(f"Pair {pair_number} incomplete. Missing: {', '.join(missing)}. Skipping this pair.")
            i = j  # Move to the next pair
        else:
            debug_print(f"Unexpected line format at line {i+1}: '{line}'. Skipping.")
            i += 1
    return pairs

def main():
    debug_print("Starting Would You Rather Generator Process")

    # Step 1: Generate 'Would You Rather' text
    debug_print("Generating Would You Rather pairs...")
    generated_text = generate_would_you_rather()
    if not generated_text:
        debug_print("Failed to generate Would You Rather pairs.")
        sys.exit(1)
    
    # Define the project output directories
    project_output_dir = Path('generated_assets')
    images_dir = project_output_dir / 'images'
    audio_dir = project_output_dir / 'audio'
    
    # Ensure directories exist
    images_dir.mkdir(parents=True, exist_ok=True)
    audio_dir.mkdir(parents=True, exist_ok=True)
    
    # Save generated text to file
    wr_file = project_output_dir / 'would_you_rather.txt'
    with open(wr_file, 'w', encoding='utf-8') as f:
        f.write(generated_text)
    debug_print(f"Generated text saved to {wr_file.resolve()}")

    # Step 2: Parse the generated text
    pairs = parse_would_you_rather_text(wr_file)
    debug_print(f"Parsed {len(pairs)} Would You Rather pairs.")

    if not pairs:
        debug_print("No valid pairs found. Exiting.")
        sys.exit(1)

    # Initialize image generator
    image_generator = ComfyUIGenerator()

    # Initialize list to hold all generated assets
    asset_list = []

    # Step 3: Generate images and audio for each pair
    for idx, pair in enumerate(pairs, start=1):
        debug_print(f"Processing pair {idx}: {pair['option1']} vs {pair['option2']}")

        # Generate images for Option 1
        debug_print(f"Generating image for Option 1: {pair['image1_desc']}")
        image1_paths = image_generator.generate_image(
            workflow_path="workflow.json", 
            prompt_text=pair['image1_desc'],
            seed=random.randint(100000000, 999999999),  # Generate a unique seed
            node_id='CLIPTextEncode',
            index=0
        )
        if not image1_paths:
            debug_print(f"Failed to generate image for Option 1: {pair['option1']}")
            continue
        # Assuming one image per prompt
        img1_filename = Path(image1_paths[0]).name
        img1_path = images_dir / img1_filename
        debug_print(f"Image for Option 1 saved as {img1_path}")

        # Generate images for Option 2
        debug_print(f"Generating image for Option 2: {pair['image2_desc']}")
        image2_paths = image_generator.generate_image(
            workflow_path="workflow.json", 
            prompt_text=pair['image2_desc'],
            seed=random.randint(100000000, 999999999),  # Generate a unique seed
            node_id='CLIPTextEncode',
            index=0
        )
        if not image2_paths:
            debug_print(f"Failed to generate image for Option 2: {pair['option2']}")
            continue
        # Assuming one image per prompt
        img2_filename = Path(image2_paths[0]).name
        img2_path = images_dir / img2_filename
        debug_print(f"Image for Option 2 saved as {img2_path}")

        # Generate TTS audio for Option 1
        debug_print(f"Generating audio for Option 1: {pair['option1']}")
        audio1_path = generate_tts(text=pair['option1'], output_dir=str(audio_dir))
        if not audio1_path:
            debug_print(f"Failed to generate audio for Option 1: {pair['option1']}")
            continue
        debug_print(f"Audio for Option 1 saved as {audio1_path}")

        # Generate TTS audio for Option 2
        debug_print(f"Generating audio for Option 2: {pair['option2']}")
        audio2_path = generate_tts(text=pair['option2'], output_dir=str(audio_dir))
        if not audio2_path:
            debug_print(f"Failed to generate audio for Option 2: {pair['option2']}")
            continue
        debug_print(f"Audio for Option 2 saved as {audio2_path}")

        # Append to asset list
        asset = {
            'option1_text': pair['option1'],
            'option2_text': pair['option2'],
            'image1_path': str(img1_path.resolve()),
            'image2_path': str(img2_path.resolve()),
            'audio1_path': audio1_path,
            'audio2_path': audio2_path
        }
        asset_list.append(asset)

    if not asset_list:
        debug_print("No assets were generated. Exiting.")
        sys.exit(1)

    # Step 4: Assemble all assets into videos
    debug_print("Assembling videos with generated assets...")

    # Initialize the video generator
    video_generator = WouldYouRatherGenerator()

    for idx, asset in enumerate(asset_list, start=1):
        # Extract timings based on audio durations
        audio1_clip = AudioFileClip(asset['audio1_path'])
        audio2_clip = AudioFileClip(asset['audio2_path'])

        # Define timings (customize as needed)
        initial_pause = 2
        timer_delay = 1
        countdown_wait = 1

        # Calculate durations based on audio lengths
        audio1_duration = audio1_clip.duration
        audio2_duration = audio2_clip.duration

        countdown_seconds = int(max(audio1_duration, audio2_duration))

        # Define percentages (you can implement logic to set these dynamically)
        percent1 = "50%"  # Placeholder value
        percent2 = "50%"  # Placeholder value

        # Generate unique output filename
        output_filename = project_output_dir / f"would_you_rather_pair_{idx}.mp4"

        debug_print(f"Generating video for pair {idx}: {asset['option1_text']} vs {asset['option2_text']}")
        video_generator.generate_video(
            option1_text=asset['option1_text'],
            option2_text=asset['option2_text'],
            image1_path=str(asset['image1_path']),
            image2_path=str(asset['image2_path']),
            percent1=percent1,
            percent2=percent2,
            initial_pause=initial_pause,
            timer_delay=timer_delay,
            countdown_wait=countdown_wait,
            countdown_seconds=countdown_seconds,
            output_filename=str(output_filename)
        )
        debug_print(f"Video for pair {idx} generated successfully: {output_filename}")

    debug_print("All videos have been generated successfully.")

if __name__ == "__main__":
    import random  # Ensure random is imported
    main()
	
	
	





here the text_generation.py:
import ollama

def generate_would_you_rather():
    prompt = """Generate 6 funny and weird 'Would You Rather' choices. 
Ensure each pair follows this exact format without deviations:

1.
CHOICE: [First choice description]
IMAGE: [First image description]
VERSUS
CHOICE: [Second choice description]
IMAGE: [Second image description]

2.
CHOICE: [First choice description]
IMAGE: [First image description]
VERSUS
CHOICE: [Second choice description]
IMAGE: [Second image description]

...

Make each pair unique, weird, and entertaining. Write detailed image descriptions that would help create a clear visual."""
    
    try:
        response = ollama.chat(model='llama3.2', messages=[
            {'role': 'user', 'content': prompt}
        ])
        return response['message']['content'].strip()
        
    except Exception as e:
        print(f"Error: {str(e)}")
        raise

def main():
    print("Generating Would You Rather pairs...")
    print("\n" + "="*50 + "\n")
    
    result = generate_would_you_rather()
    print(result)
    
    # Save to file
    with open('would_you_rather.txt', 'w', encoding='utf-8') as f:
        f.write(result)
    
    print("\n" + "="*50)
    print("\nResults have been saved to would_you_rather.txt")

if __name__ == "__main__":
    main()
	
	
	


here the image generaiton.py:
# image_generation.py

import websocket
import uuid
import json
import urllib.request
import urllib.parse
import random
import os
from pathlib import Path
from io import BytesIO

class ComfyUIGenerator:
    def __init__(self, server_address="127.0.0.1:8188"):
        self.server_address = server_address
        self.client_id = str(uuid.uuid4())
        
        # Create generate_assets/images and generate_assets/audio folders if they don't exist
        Path("generated_assets/images").mkdir(parents=True, exist_ok=True)
        Path("generated_assets/audio").mkdir(parents=True, exist_ok=True)
        
    def load_workflow(self, workflow_path):
        """Load workflow JSON from file"""
        with open(workflow_path, 'r') as f:
            return json.load(f)
            
    def queue_prompt(self, prompt):
        """Queue a prompt on the ComfyUI server"""
        p = {"prompt": prompt, "client_id": self.client_id}
        data = json.dumps(p).encode('utf-8')
        req = urllib.request.Request(f"http://{self.server_address}/prompt", data=data)
        return json.loads(urllib.request.urlopen(req).read())

    def get_image(self, filename, subfolder, folder_type):
        """Get image data from the server"""
        data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
        url_values = urllib.parse.urlencode(data)
        with urllib.request.urlopen(f"http://{self.server_address}/view?{url_values}") as response:
            return response.read()

    def get_history(self, prompt_id):
        """Get history data for a prompt"""
        with urllib.request.urlopen(f"http://{self.server_address}/history/{prompt_id}") as response:
            return json.loads(response.read())

    def save_image(self, image_data, filename):
        """Save image data to file"""
        output_path = Path("generate_images") / filename
        with open(output_path, 'wb') as f:
            f.write(image_data)
        print(f"Image saved to: {output_path}")
        return str(output_path)

    def get_images(self, ws, prompt):
        """Get images using the history endpoint"""
        prompt_id = self.queue_prompt(prompt)['prompt_id']
        
        # Wait for execution to complete
        while True:
            out = ws.recv()
            if isinstance(out, str):
                message = json.loads(out)
                if message['type'] == 'executing':
                    data = message['data']
                    if data['node'] is None and data['prompt_id'] == prompt_id:
                        break
            else:
                continue  # Skip binary messages (previews)

        # Get the images from history
        history = self.get_history(prompt_id)[prompt_id]
        output_images = {}
        
        for node_id in history['outputs']:
            node_output = history['outputs'][node_id]
            images_output = []
            if 'images' in node_output:
                for image in node_output['images']:
                    image_data = self.get_image(
                        image['filename'], 
                        image['subfolder'], 
                        image['type']
                    )
                    images_output.append(image_data)
            output_images[node_id] = images_output
            
        return output_images, prompt_id

    def generate_image(self, workflow_path, prompt_text, seed=None, node_id='CLIPTextEncode', index=0):
        """Generate an image using the workflow"""
        # Load the workflow
        workflow = self.load_workflow(workflow_path)
        
        # Generate random seed if none provided
        if seed is None:
            seed = random.randint(0, 1000000000)
            
        # Find the CLIPTextEncode node for positive prompt
        for nid, node in workflow.items():
            if node.get("class_type") == "CLIPTextEncode" and \
               "_meta" in node and \
               "title" in node["_meta"] and \
               "Positive" in node["_meta"]["title"]:
                node["inputs"]["text"] = prompt_text
                
        # Find the KSampler node to update the seed
        for nid, node in workflow.items():
            if node.get("class_type") == "KSampler":
                node["inputs"]["seed"] = seed

        # Connect to websocket
        ws = websocket.WebSocket()
        ws.connect(f"ws://{self.server_address}/ws?clientId={self.client_id}")
        
        try:
            # Get images using history endpoint
            images, prompt_id = self.get_images(ws, workflow)
            
            # Save all generated images with consistent naming
            saved_image_paths = []
            for node_id_key, image_list in images.items():
                for i, image_data in enumerate(image_list):
                    filename = f"generated_{seed}_{node_id}_{i}.png"
                    image_path = Path("generated_assets/images") / filename
                    with open(image_path, 'wb') as f:
                        f.write(image_data)
                    print(f"[DEBUG] Image saved to: {image_path}")
                    saved_image_paths.append(str(image_path))
                    
            return saved_image_paths
                
        finally:
            ws.close()
            
def main():
    # Initialize the generator
    generator = ComfyUIGenerator()
    
    # Example prompts
    prompts = [
        "a beautiful landscape with mountains",
        "a cyberpunk city at night",
        "a serene beach at sunset",
        "an enchanted forest with magical creatures"
    ]
    
    # Generate multiple images with different prompts
    workflow_path = "workflow.json"  # Make sure this file exists
    
    for prompt in prompts:
        print(f"\nGenerating image for prompt: {prompt}")
        try:
            saved_images = generator.generate_image(workflow_path, prompt)
            print(f"Generated images: {saved_images}")
        except Exception as e:
            print(f"Error generating image for prompt '{prompt}': {str(e)}")

if __name__ == "__main__":
    main()






here the voice_generation.py:
# voice_generation.py

import os
import subprocess
from pathlib import Path
import shutil
import datetime
import argparse

def generate_tts(text, base_dir=None, ref_audio=None, output_dir=None):
    """
    Generate TTS audio using F5-TTS model.
    
    Args:
        text (str): Text to convert to speech
        base_dir (str, optional): Base directory where F5-TTS is installed
        ref_audio (str, optional): Path to reference audio file
        output_dir (str, optional): Directory to save output files
    """
    if base_dir is None:
        base_dir = r"C:\Users\theod\Desktop\AI\text2voice\F5-TTS"
    
    if ref_audio is None:
        ref_audio = os.path.join(base_dir, "tests", "ref_audio", "tiktok.mp3")
    
    if output_dir is None:
        output_dir = os.path.join(r"C:\Users\theod\Desktop\Coding\AI\wouldyourather\generated_assets\audio")
    
    # Create output directory if it doesn't exist
    os.makedirs(output_dir, exist_ok=True)
    
    # Reference text that matches your sample
    ref_text = "Never go to school again. Or, Get paid to go to school. Be able to fly like a bird or be able to swim like a fish. Have a long but ordinary life or have a short but extraordinary life I love God or reject the offer have a ferrari."
    
    # Build the command with proper quoting
    cmd = [
        "python", "inference-cli.py",
        "--model", "F5-TTS",
        "--ref_audio", f'"{ref_audio}"',
        "--ref_text", f'"{ref_text}"',
        "--gen_text", f'"{text}"'
    ]
    
    try:
        # Change to the base directory
        original_dir = os.getcwd()
        os.chdir(base_dir)
        
        # Combine command with proper quoting
        command_str = " ".join(cmd)
        
        # Activate virtual environment and run command
        if os.name == 'nt':  # Windows
            activate_cmd = os.path.join(base_dir, "venv", "Scripts", "activate.bat")
            full_command = f'call "{activate_cmd}" && {command_str}'
            subprocess.run(full_command, shell=True, check=True)
        else:  # Linux/Mac
            activate_cmd = os.path.join(base_dir, "venv", "bin", "activate")
            full_command = f'source "{activate_cmd}" && {command_str}'
            subprocess.run(full_command, shell=True, check=True)
        
        # Copy the output file to our designated output directory
        output_file = os.path.join(base_dir, "tests", "out.wav")
        if os.path.exists(output_file):
            timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
            new_filename = f"tts_output_{timestamp}.wav"
            new_filepath = os.path.join(output_dir, new_filename)
            shutil.copy2(output_file, new_filepath)
            print(f"[DEBUG] Audio generated successfully: {new_filepath}")
            return new_filepath
        else:
            print("[DEBUG] Error: Output file not found")
            return None
            
    except subprocess.CalledProcessError as e:
        print(f"[DEBUG] Command execution failed: {str(e)}")
        return None
    except Exception as e:
        print(f"[DEBUG] Error occurred: {str(e)}")
        return None
    finally:
        # Return to original directory
        os.chdir(original_dir)

def main():
    parser = argparse.ArgumentParser(description='Generate TTS audio using F5-TTS')
    parser.add_argument('--text', type=str, required=True, help='Text to convert to speech')
    args = parser.parse_args()
    
    output_path = generate_tts(args.text)
    if output_path:
        print(f"Generated audio saved to: {output_path}")

if __name__ == "__main__":
    main()






and here the voice_generation.py:
# video_generation.py

import os
from moviepy.editor import (
    TextClip,
    ColorClip,
    CompositeVideoClip,
    ImageClip,
)
from moviepy.config import change_settings
import numpy as np
from PIL import Image, ImageDraw

# Configure ImageMagick (Ensure this path is correct for your system)
change_settings(
    {"IMAGEMAGICK_BINARY": r"C:\Program Files\ImageMagick-7.1.1-Q16-HDRI\magick.exe"}
)


class WouldYouRatherGenerator:
    def __init__(self):
        # Initialize video parameters
        self.width = 1080
        self.height = 1920
        self.middle_y = self.height // 2

    def process_image(self, image_path, size=(500, 500), start_time=0, duration=0):
        """
        Process the image by converting mode and resizing proportionally without warping.
        """
        debug_print = lambda msg: print(f"[DEBUG] {msg}")
        debug_print(f"Processing image: {image_path}")

        if not os.path.exists(image_path):
            debug_print(f"Image file does not exist: {image_path}")
            return None

        img = Image.open(image_path)

        if img.mode != "RGBA":
            img = img.convert("RGBA")

        # Resize image proportionally if size is provided
        if size:
            img.thumbnail(size, Image.LANCZOS)  # In-place resizing

        img_array = np.array(img)

        clip_duration = duration if duration > 0 else self.total_duration

        clip = ImageClip(img_array).set_duration(clip_duration)

        if start_time > 0:
            clip = clip.set_start(start_time)

        debug_print(f"Image processed: {image_path}")
        return clip

    def create_styled_text(
        self, text, y_position, duration, start_time=0, fontsize=70, color="yellow",
        stroke_color="black", stroke_width=2
    ):
        """
        Create a styled TextClip.
        """
        debug_print = lambda msg: print(f"[DEBUG] {msg}")

        debug_print(f"Creating styled text: {text} at position {y_position}")
        text_clip = TextClip(
            text,
            font="Arial-Bold",
            color=color,
            fontsize=fontsize,
            method="label",  # Changed to 'label' for better positioning
            stroke_color=stroke_color,
            stroke_width=stroke_width,
        ).set_duration(duration)

        if start_time > 0:
            text_clip = text_clip.set_start(start_time)

        debug_print(f"Styled text created: {text}")
        return text_clip.set_position(("center", y_position))

    def create_timer_clips(self, start_time, countdown_seconds, total_duration):
        """
        Create countdown timer clips from countdown_seconds to 1 (excluding 0).
        """
        timer_clips = []
        for i in range(countdown_seconds, 0, -1):  # Excludes 0
            current_time = countdown_seconds - i
            timer_text = str(i)
            timer_duration = 1  # Each number shows for 1 second
            timer_clip = self.create_styled_text(
                timer_text,
                self.middle_y - 100,  # Positioned slightly above the center
                timer_duration,
                start_time + current_time,
                fontsize=150,
                color="white",
                stroke_color="black",
                stroke_width=3
            )
            timer_clips.append(timer_clip)
        return timer_clips

    def generate_video(
        self,
        option1_text,
        option2_text,
        image1_path,
        image2_path,
        percent1="50%",
        percent2="50%",
        initial_pause=2,
        timer_delay=1,
        countdown_wait=1,
        countdown_seconds=5,
        output_filename="would_you_rather.mp4"
    ):
        """
        Generate the 'Would You Rather' video based on provided parameters.
        """
        debug_print = lambda msg: print(f"[DEBUG] {msg}")

        debug_print(f"Starting video generation: {output_filename}")

        # Define percentage display duration and desired extra time
        percentage_duration = 3  # seconds (increased from 2)
        desired_extra_time = 0    # seconds (no extra buffer after percentages)

        # Calculate buffer_time as the sum of percentage_duration and desired_extra_time
        buffer_time = percentage_duration + desired_extra_time  # 3 + 0 = 3 seconds

        # Calculate total_duration
        self.total_duration = (
            initial_pause
            + timer_delay
            + countdown_wait
            + countdown_seconds
            + buffer_time
        )  # e.g., 2 + 1 + 1 + 5 + 3 = 12 seconds

        debug_print(f"Total video duration: {self.total_duration} seconds")

        # Create background clips
        red_clip = ColorClip((self.width, self.middle_y), color=(255, 0, 0)).set_duration(
            self.total_duration
        )
        blue_clip = ColorClip((self.width, self.middle_y), color=(0, 0, 255)).set_duration(
            self.total_duration
        )

        clips = [
            red_clip.set_position((0, 0)),
            blue_clip.set_position((0, self.middle_y)),
        ]

        # Fixed Positions

        # Top Half
        top_image_y = 250    # Moved further down from 200 to 250
        top_text_y = 650     # Moved up by 50 pixels from 700 to 650
        top_percentage_y = 750  # Moved up by 50 pixels from 800 to 750

        # Bottom Half
        bottom_image_y = self.middle_y + 350  # Moved further down from self.middle_y + 300 to +350
        bottom_text_y = 1200  # Fixed position for bottom text
        bottom_percentage_y = 1100  # Changed from 1300 to 1100 to place above the bottom text

        # Add top image (Option 1) with initial_pause delay
        img1_clip = self.process_image(
            image1_path,
            size=(500, 500),       # Increased size to 500x500
            start_time=initial_pause,          # Starts after initial_pause
            duration=self.total_duration - initial_pause  # Adjust duration accordingly
        )
        if img1_clip:
            clips.append(img1_clip.set_position(("center", top_image_y)))
        else:
            debug_print("Failed to add Option 1 image clip.")

        # Add top text with initial_pause delay
        option1_txt = self.create_styled_text(
            option1_text.upper(),
            y_position=top_text_y,
            duration=self.total_duration - initial_pause,  # Duration until end
            start_time=initial_pause,          # Starts after initial_pause
            fontsize=80,
            color="white",
            stroke_color="black",
            stroke_width=3
        )
        clips.append(option1_txt)

        # Add bottom image (Option 2) after initial_pause + timer_delay
        img2_start_time = initial_pause + timer_delay
        img2_clip = self.process_image(
            image2_path,
            size=(500, 500),       # Increased size to 500x500
            start_time=img2_start_time,
            duration=self.total_duration - img2_start_time  # Adjust duration accordingly
        )
        if img2_clip:
            clips.append(img2_clip.set_position(("center", bottom_image_y)).set_start(img2_start_time))
        else:
            debug_print("Failed to add Option 2 image clip.")

        # Add bottom text below the bottom image after initial_pause + timer_delay
        option2_txt = self.create_styled_text(
            option2_text.upper(),
            y_position=bottom_text_y,
            duration=self.total_duration - img2_start_time,  # Duration until the end
            start_time=img2_start_time,
            fontsize=80,
            color="white",
            stroke_color="black",
            stroke_width=3
        )
        clips.append(option2_txt)

        # Add dividing line
        line_thickness = 8
        black_line = ColorClip((self.width, line_thickness), color=(0, 0, 0)).set_duration(self.total_duration)
        black_line = black_line.set_position((0, self.middle_y - line_thickness // 2))
        clips.append(black_line)

        # Add small black circle in the middle of the dividing line
        circle_diameter = 50  # Adjust size as needed
        circle_size = (circle_diameter, circle_diameter)

        # Create a transparent image with a black circle
        circle_img = Image.new("RGBA", circle_size, (0, 0, 0, 0))
        draw = ImageDraw.Draw(circle_img)
        draw.ellipse((0, 0, circle_diameter, circle_diameter), fill=(0, 0, 0, 255))
        circle_array = np.array(circle_img)

        # Create ImageClip for the circle
        circle_clip = ImageClip(circle_array).set_duration(self.total_duration)
        # Position the circle in the middle of the dividing line
        circle_position = (self.width // 2 - circle_diameter // 2, self.middle_y - circle_diameter // 2)
        clips.append(circle_clip.set_position(circle_position))

        # Add countdown timer after initial_pause + timer_delay + countdown_wait
        countdown_start_time = initial_pause + timer_delay + countdown_wait
        timer_clips = self.create_timer_clips(countdown_start_time, countdown_seconds, self.total_duration)
        clips.extend(timer_clips)

        # Add Percentage 1 Text ("50%") in Yellow after countdown
        percent1_txt = self.create_styled_text(
            f"{percent1}",
            y_position=top_percentage_y,
            duration=3,  # seconds
            start_time=countdown_start_time + countdown_seconds,
            fontsize=100,  # Increased font size
            color="yellow",
            stroke_color="black",
            stroke_width=2
        )
        clips.append(percent1_txt)

        # Add Percentage 2 Text ("50%") in Yellow above the bottom text after countdown
        percent2_txt = self.create_styled_text(
            f"{percent2}",
            y_position=bottom_percentage_y,
            duration=3,  # seconds
            start_time=countdown_start_time + countdown_seconds,
            fontsize=100,  # Increased font size
            color="yellow",
            stroke_color="black",
            stroke_width=2
        )
        clips.append(percent2_txt)

        # Create final video
        debug_print("Creating CompositeVideoClip...")
        final_clip = CompositeVideoClip(clips, size=(self.width, self.height))
        debug_print("CompositeVideoClip created.")

        # Render the video
        debug_print(f"Rendering video to {output_filename}...")
        final_clip.write_videofile(
            output_filename,
            fps=30,
            codec="libx264",
            audio=False,
            threads=4,
            preset="medium",
        )
        debug_print(f"Video generated and saved as {output_filename}")
		




fix the issues. only reply with the code I need to update.