Spaces:
Runtime error
Runtime error
| from PIL import Image, ImageDraw, ImageFont | |
| import cv2 | |
| import numpy as np | |
| import textwrap | |
| def generate_lyric_frame(lyric, image_size): | |
| # If image_size is None, provide a default value | |
| if image_size is None: | |
| image_size = (800, 600) # Example default size, you can change this | |
| # Ensure image_size is a tuple | |
| image_size = tuple(image_size) | |
| image = Image.new('RGB', image_size, color='black') | |
| draw = ImageDraw.Draw(image) | |
| # Use PIL's default font | |
| font = ImageFont.load_default() | |
| # Wrap text | |
| max_width = image_size[0] - 40 # Keeping 20 pixels margin on each side | |
| wrapped_text = textwrap.fill(lyric, width=40) | |
| lines = wrapped_text.split('\n') | |
| # Calculate text width and height | |
| text_width = max(draw.textlength(line, font=font) for line in lines) # Corrected line here | |
| text_height = sum([font.getmask(line).getbbox()[3] for line in lines if font.getmask(line).getbbox()]) # Corrected line here | |
| # Calculate starting coordinates to center the text block | |
| text_x = (image_size[0] - text_width) / 2 | |
| text_y = (image_size[1] - text_height) / 2 | |
| # Draw the wrapped text on the image | |
| y = text_y | |
| for line in lines: | |
| draw.text((text_x, y), line, font=font, fill='white') | |
| y += font.getmask(line).getbbox()[3] if font.getmask(line).getbbox() else 0 # Corrected line here | |
| return image | |
| def generate_video(lyrics_with_timing, image_size=(800, 600), frame_rate=30): | |
| frames = [] | |
| for start_time, end_time, lyric in lyrics_with_timing: | |
| # Calculate the number of frames for this lyric segment | |
| num_frames = int((end_time - start_time) * frame_rate) | |
| # Create frames with the lyric text | |
| for _ in range(num_frames): | |
| frame = generate_lyric_frame(lyric, image_size) | |
| frames.append(frame) | |
| # Combine frames into a video | |
| video = combine_frames_into_video(frames, frame_rate) | |
| return video | |
| def combine_frames_into_video(frames, frame_rate): | |
| # Convert the first frame to a NumPy array to get its shape | |
| first_frame_np = np.array(frames[0]) | |
| height, width, _ = first_frame_np.shape | |
| # Define the codec and create a video writer object | |
| fourcc = cv2.VideoWriter_fourcc(*'XVID') | |
| out = cv2.VideoWriter('output.avi', fourcc, frame_rate, (width, height)) | |
| # Write each frame to the video file | |
| for frame in frames: | |
| # Convert PIL image to NumPy array | |
| frame_np = np.array(frame) | |
| # Convert RGB to BGR as OpenCV uses BGR format | |
| frame_bgr = cv2.cvtColor(frame_np, cv2.COLOR_RGB2BGR) | |
| # Write the BGR frame to the video | |
| out.write(frame_bgr) | |
| # Release the video writer object | |
| out.release() | |
| return 'output.avi' | |