Spaces:
Sleeping
Sleeping
import gradio as gr | |
import cv2 | |
import numpy as np | |
from PIL import Image, ImageDraw, ImageFont | |
import textwrap | |
import moviepy.editor as mp | |
import moviepy.video.fx.all as vfx | |
css = """ | |
#col-container { | |
margin: 0 auto; | |
max-width: 290px; | |
} | |
""" | |
def create_typing_video(code_text, format_choice, line_spacing, width_choice, height_choice, font_name="arial.ttf", font_size=18, frame_rate=10, sound_choice=None, custom_audio=None, background_color="black", text_color="white", enhance_quality=False, video_speed="1.0"): | |
font_path = f"font/{font_name}" | |
# Convert font_size to integer | |
font_size = int(font_size) | |
font = ImageFont.truetype(font_path, font_size) | |
video_frames = [] | |
image_width, image_height = int(width_choice), int(height_choice) | |
max_width = image_width - 40 # Margin of 20 pixels on each side | |
current_text = "" | |
background = Image.new("RGB", (image_width, image_height), color=background_color) | |
while True: | |
wrapped_lines = textwrap.wrap(code_text, width=max_width // font.getlength(' ')) | |
text_height = sum([font.getbbox(line)[3] - font.getbbox(line)[1] for line in wrapped_lines]) | |
if text_height <= image_height - 40: | |
break | |
font_size -= 1 | |
font = ImageFont.truetype(font_path, font_size) | |
for char in code_text: | |
current_text += char | |
if format_choice == "Paragraph": | |
wrapped_lines = textwrap.wrap(current_text, width=max_width // font.getlength(' ')) | |
else: | |
wrapped_lines = current_text.splitlines() | |
image = background.copy() | |
draw = ImageDraw.Draw(image) | |
y_position = 20 | |
for line in wrapped_lines: | |
draw.text((20, y_position), line, font=font, fill=text_color) | |
line_height = font.getbbox(line)[3] - font.getbbox(line)[1] | |
y_position += line_height * line_spacing | |
frame = np.array(image) | |
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) | |
video_frames.append(frame) | |
video_filename = "typed_code_video.mp4" | |
out = cv2.VideoWriter(video_filename, cv2.VideoWriter_fourcc(*"mp4v"), frame_rate, (image_width, image_height)) | |
for frame in video_frames: | |
out.write(frame) | |
out.release() | |
speed_factor = { | |
"1x": 1.0, | |
"1.25x": 1.25, | |
"1.5x": 1.5, | |
"1.75x": 1.75, | |
"2x": 2.0 | |
}.get(video_speed, 1.0) | |
video = mp.VideoFileClip(video_filename).fx(vfx.speedx, factor=speed_factor) | |
video.write_videofile("speed_adjusted_video.mp4", codec="libx264") | |
video_filename = "speed_adjusted_video.mp4" | |
if sound_choice and sound_choice != "No Sound": | |
video = mp.VideoFileClip(video_filename) | |
audio = mp.AudioFileClip(f"type-sounds/{sound_choice}") | |
audio = audio.fx(mp.afx.audio_loop, duration=video.duration) | |
video = video.set_audio(audio) | |
video.write_videofile("typed_code_video_with_sound.mp4", codec="libx264") | |
video_filename = "typed_code_video_with_sound.mp4" | |
if custom_audio: | |
video = mp.VideoFileClip(video_filename) | |
audio = mp.AudioFileClip(custom_audio) | |
audio = audio.fx(mp.afx.audio_loop, duration=video.duration) | |
video = video.set_audio(audio) | |
video.write_videofile("typed_code_video_with_custom_audio.mp4", codec="libx264") | |
video_filename = "typed_code_video_with_custom_audio.mp4" | |
if enhance_quality: | |
video = mp.VideoFileClip(video_filename) | |
video = video.fx(vfx.resize, height=720) | |
video = video.fx(vfx.colorx, 1.2) | |
video.write_videofile("enhanced_" + video_filename, codec="libx264") | |
video_filename = "enhanced_" + video_filename | |
return video_filename | |
def generate_video(code_text, format_choice, line_spacing, width_choice, height_choice, font_choice, font_size, sound_choice, custom_audio, background_color, text_color, enhance_quality, video_speed): | |
return create_typing_video(code_text, format_choice, line_spacing, width_choice, height_choice, font_name=font_choice, font_size=font_size, sound_choice=sound_choice, custom_audio=custom_audio, background_color=background_color, text_color=text_color, enhance_quality=enhance_quality, video_speed=video_speed) | |
iface = gr.Interface( | |
fn=generate_video, | |
inputs=[ | |
gr.Textbox(label="Enter Content", lines=10, placeholder="Enter the text to be displayed in the video..."), | |
gr.Dropdown(choices=["Paragraph", "Programming"], value="Paragraph", label="Text Format"), | |
gr.Dropdown(choices=[1.0, 1.15, 1.5, 2.0, 2.5, 3.0], value=1.5, label="Line Spacing"), | |
gr.Dropdown(choices=["400", "800", "1024", "1280", "1920"], value="800", label="Video Width"), | |
gr.Dropdown(choices=["400", "720", "1080", "1440", "2160"], value="400", label="Video Height"), | |
gr.Dropdown(choices=["arial.ttf", "times new roman.ttf"], value="arial.ttf", label="Font Choice"), | |
gr.Dropdown(choices=["16", "18", "20", "22", "24"], value="18", label="Font Size"), | |
gr.Dropdown(choices=["No Sound", "Typing.mp3"], value="No Sound", label="Sound Choice"), | |
gr.File(label="Upload Custom Audio SFX🔊", type="filepath"), | |
gr.Dropdown(choices=["black", "white"], value="black", label="Background Color"), | |
gr.Dropdown(choices=["black", "white"], value="white", label="Text Color"), | |
gr.Checkbox(label="Enhance Video Quality"), | |
gr.Dropdown(choices=["1x", "1.25x", "1.5x"], value="1x", label="Video Speed"), | |
], | |
outputs=gr.Video(label="Typing Video"), | |
title="Type Bytes🐧", | |
css=css, | |
) | |
if __name__ == "__main__": | |
iface.launch(share=True) |