Ytstock / app.py
Artificial-superintelligence's picture
Update app.py
735f163 verified
raw
history blame
3.91 kB
import gradio as gr
import yt_dlp
import os
import re
import time
from moviepy.video.io.VideoFileClip import VideoFileClip
# Function to sanitize the filename
def sanitize_filename(title):
# Replace invalid characters with an underscore
return re.sub(r'[<>:"/\\|?*]', '_', title)
# Function to download video and return the file path
def download_video(url):
# Use /tmp for temporary storage in Hugging Face Spaces
download_path = '/tmp/downloads'
if not os.path.exists(download_path):
os.makedirs(download_path)
ydl_opts = {
'outtmpl': os.path.join(download_path, '%(title)s.%(ext)s'),
'format': 'mp4/bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', # Prefer MP4 format
'merge_output_format': 'mp4',
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info_dict = ydl.extract_info(url, download=True)
title = info_dict.get('title', None)
if title:
sanitized_title = sanitize_filename(title)
file_path = os.path.join(download_path, f"{sanitized_title}.mp4")
return file_path if os.path.exists(file_path) else None
return None
except Exception as e:
print(f"Download error: {str(e)}")
return None
# Function to crop the video
def crop_video(input_path, start_time, end_time):
if not input_path or not os.path.exists(input_path):
return None
output_path = os.path.join('/tmp/downloads', 'cropped_video.mp4')
try:
with VideoFileClip(input_path) as video:
# Ensure end_time doesn't exceed video duration
duration = video.duration
end_time = min(end_time, duration)
if start_time >= end_time:
return None
cropped_video = video.subclip(start_time, end_time)
cropped_video.write_videofile(output_path, codec='libx264', audio_codec='aac')
return output_path if os.path.exists(output_path) else None
except Exception as e:
print(f"Cropping error: {str(e)}")
return None
# Main processing function
def process_video(url, start_time, end_time):
if not url:
return None
try:
# Download the video
video_path = download_video(url)
if not video_path:
return None
# Crop the video
cropped_path = crop_video(video_path, start_time, end_time)
if cropped_path and os.path.exists(cropped_path):
time.sleep(1) # Ensure file is fully written
return cropped_path
return None
except Exception as e:
print(f"Processing error: {str(e)}")
return None
# Create Gradio interface
def create_interface():
with gr.Blocks() as demo:
gr.Markdown("# YouTube Video Downloader and Cropper")
with gr.Row():
url_input = gr.Textbox(
label="YouTube URL",
placeholder="Enter YouTube video URL here..."
)
with gr.Row():
start_time_input = gr.Number(
label="Start Time (seconds)",
value=0,
minimum=0
)
end_time_input = gr.Number(
label="End Time (seconds)",
value=10,
minimum=0
)
with gr.Row():
process_btn = gr.Button("Download and Crop Video")
output_file = gr.File(label="Download Cropped Video")
# Connect the button to the processing function
process_btn.click(
fn=process_video,
inputs=[url_input, start_time_input, end_time_input],
outputs=output_file
)
return demo
# Launch the app
demo = create_interface()
demo.launch()