ShortsAutomator / app.py
TIMBOVILL's picture
Update app.py
4d660a6 verified
raw
history blame
4.11 kB
import os
import random
import gradio as gr
from moviepy.editor import VideoFileClip, CompositeVideoClip, ImageClip
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import subprocess
# Ensure ImageMagick is installed
def install_imagemagick():
if not os.path.exists('/usr/bin/convert'):
subprocess.run(['apt-get', 'update'])
subprocess.run(['apt-get', 'install', '-y', 'imagemagick'])
install_imagemagick()
import gradio as gr
import os
from moviepy.editor import VideoFileClip, CompositeVideoClip, ImageClip
from PIL import Image, ImageDraw, ImageFont
def create_text_clip(text, fontsize=70, color='white', size=(1080, 1920)):
font = ImageFont.truetype("arial.ttf", fontsize)
img = Image.new('RGBA', size, (0, 0, 0, 0))
draw = ImageDraw.Draw(img)
w, h = draw.textbbox((0, 0), text, font=font)[2:]
draw.text(((size[0] - w) / 2, (size[1] - h) / 2), text, font=font, fill=color)
return img
def process_video(video_file, text):
# Convert video_file string path to a file object and then extract the path
video_path = video_file.name if isinstance(video_file, gr.inputs.File) else video_file
if not os.path.isfile(video_path):
raise FileNotFoundError(f"The file {video_path} does not exist.")
video = VideoFileClip(video_path)
# Calculate new width to maintain the 9:16 aspect ratio
new_width = int(video.h * 9 / 16)
# Resize video to maintain 9:16 aspect ratio
video = video.resize(width=new_width)
# Create a text image
text_img = create_text_clip(text, fontsize=70, color='white', size=(new_width, video.h))
# Convert the text image to an ImageClip
text_clip = ImageClip(text_img).set_duration(video.duration)
# Composite the video with the text clip
final_clip = CompositeVideoClip([video, text_clip])
# Save the final video
output_path = "/mnt/data/output_video.mp4"
final_clip.write_videofile(output_path, codec="libx264", fps=24)
return output_path
# Additional inputs for the chat interface
additional_inputs = [
gr.Dropdown(choices=["llama3-70b-8192", "llama3-8b-8192", "mixtral-8x7b-32768", "gemma-7b-it"], value="llama3-70b-8192", label="Model"),
gr.Slider(minimum=0.0, maximum=1.0, step=0.01, value=0.5, label="Temperature", info="Controls diversity of the generated text. Lower is more deterministic, higher is more creative."),
gr.Slider(minimum=1, maximum=32192, step=1, value=4096, label="Max Tokens", info="The maximum number of tokens that the model can process in a single response.<br>Maximums: 8k for gemma 7b, llama 7b & 70b, 32k for mixtral 8x7b."),
gr.Slider(minimum=0.0, maximum=1.0, step=0.01, value=0.5, label="Top P", info="A method of text generation where a model will only consider the most probable next tokens that make up the probability p."),
gr.Number(precision=0, value=42, label="Seed", info="A starting point to initiate generation, use 0 for random")
]
# Gradio interface with blocks and tabs
# Chat Interface
def create_chat_interface():
return gr.ChatInterface(
fn=generate_response,
chatbot=gr.Chatbot(
show_label=False,
show_share_button=False,
show_copy_button=True,
likeable=True,
layout="panel"
),
additional_inputs=additional_inputs,
title="YTSHorts Maker",
description="Powered by GROQ, MoviePy, and other tools."
)
# Main app definition
with gr.Blocks(theme=gr.themes.Soft(primary_hue="red", secondary_hue="pink")) as demo:
with gr.Tabs():
# Chat Ta
with gr.TabItem("Video Processing"):
text_input = gr.Textbox(lines=5, label="Text (8 words max per line)")
process_button = gr.Button("Process Video")
video_output = gr.Video(label="Processed Video")
process_button.click(
fn=process_video,
inputs=text_input,
outputs=video_output,
)
# Launch the Gradio interface
if __name__ == "__main__":
demo.launch()