Spaces:
Sleeping
Sleeping
#This was made with ChatGPT because my dumbass can't actually code | |
import os | |
import subprocess | |
import uuid | |
import glob | |
import shutil | |
import gradio as gr | |
# Set default acceleration and extra encoding options. | |
accel = 'auto' | |
extra = '-crf 63 -c:v libx264' # default extra settings | |
# Fixed upload and conversion folders. | |
UPLOAD_FOLDER = 'uploads' | |
CONVERTED_FOLDER = 'converted' | |
os.makedirs(UPLOAD_FOLDER, exist_ok=True) | |
os.makedirs(CONVERTED_FOLDER, exist_ok=True) | |
# Helper function to configure audio options. | |
def configure_audio(cmd_list, use_mp3): | |
if use_mp3: | |
cmd_list.extend(['-c:a', 'libmp3lame', '-b:a', '8k', '-ar', '24k', '-ac', '1']) | |
else: | |
cmd_list.extend(['-c:a', 'aac', '-b:a', '1k', '-ar', '8k', '-ac', '1']) | |
def convert_video(use_youtube, youtube_url, video_file, downscale, faster, use_mp3, audio_only): | |
""" | |
Converts a video either from a YouTube URL or an uploaded file. | |
Returns a tuple (preview_file, download_file) with the output path. | |
""" | |
# Determine output filename based on whether only audio is desired. | |
if audio_only: | |
output_filename = f"{uuid.uuid4()}.mp3" if use_mp3 else f"{uuid.uuid4()}.aac" | |
else: | |
output_filename = f"{uuid.uuid4()}.mp4" | |
output_path = os.path.join(CONVERTED_FOLDER, output_filename) | |
if use_youtube: | |
if not youtube_url: | |
return "Error: YouTube URL is required.", None | |
# Determine quality: if downscale is ticked use low quality; otherwise, use "-f b" for best quality. | |
quality = 'worstaudio' if audio_only and downscale else ( | |
'worstvideo+worstaudio' if downscale else 'b') | |
yt_uuid = str(uuid.uuid4()) | |
yt_input_filename = yt_uuid + ".%(ext)s" | |
yt_input_path = os.path.join(UPLOAD_FOLDER, yt_input_filename) | |
yt_dlp_cmd = ['yt-dlp', '-o', yt_input_path, '-f', quality, youtube_url] | |
try: | |
subprocess.run(yt_dlp_cmd, check=True) | |
except subprocess.CalledProcessError as e: | |
return f"An error occurred during YouTube download: {e}", None | |
# Locate the downloaded file (yt-dlp replaces %(ext)s with the actual extension). | |
pattern = os.path.join(UPLOAD_FOLDER, yt_uuid + ".*") | |
downloaded_files = glob.glob(pattern) | |
if not downloaded_files: | |
return "Failed to download YouTube video.", None | |
input_path = downloaded_files[0] | |
else: | |
# File upload branch. | |
if not video_file: | |
return "Error: No video file provided.", None | |
# Check if the provided file path exists. | |
if os.path.exists(video_file): | |
ext = os.path.splitext(video_file)[1] | |
input_filename = f"{uuid.uuid4()}{ext}" | |
input_path = os.path.join(UPLOAD_FOLDER, input_filename) | |
# Copy the file to our uploads folder. | |
shutil.copy2(video_file, input_path) | |
else: | |
# If the file doesn't exist (perhaps already in a persistent location), reuse it. | |
input_path = video_file | |
# Build the FFmpeg command. | |
ffmpeg_cmd = ['ffmpeg', '-hwaccel', accel, '-y', '-i', input_path] + extra.split() | |
if downscale: | |
ffmpeg_cmd.extend(['-vf', 'scale=144:-2']) | |
if faster: | |
ffmpeg_cmd.extend(['-preset', 'ultrafast']) | |
if audio_only: | |
ffmpeg_cmd.extend(['-vn']) | |
configure_audio(ffmpeg_cmd, use_mp3) | |
else: | |
configure_audio(ffmpeg_cmd, use_mp3) | |
ffmpeg_cmd.append(output_path) | |
try: | |
subprocess.run(ffmpeg_cmd, check=True) | |
except subprocess.CalledProcessError as e: | |
return f"An error occurred during conversion: {e}", None | |
# Return the same output for preview and download. | |
return output_path, output_path | |
# Create the Gradio interface. | |
with gr.Blocks() as demo: | |
gr.Markdown("## Low Quality Video Inator") | |
gr.Markdown("Upload a video or use a YouTube URL and adjust the options below.") | |
with gr.Row(): | |
use_youtube = gr.Checkbox(label="Use YouTube URL (almost never works)", value=False) | |
youtube_url = gr.Textbox(label="YouTube URL", placeholder="Enter YouTube URL here") | |
video_file = gr.File(label="Upload Video") | |
with gr.Row(): | |
downscale = gr.Checkbox(label="Downscale Video (144p)", value=False) | |
faster = gr.Checkbox(label="Faster Conversion (more pixelated)", value=False) | |
with gr.Row(): | |
use_mp3 = gr.Checkbox(label="Use MP3 (video audio compression)", value=False) | |
audio_only = gr.Checkbox(label="Only Audio (no video)", value=False) | |
convert_button = gr.Button("Convert Video") | |
gr.Markdown("### Preview Converted Video") | |
video_preview = gr.Video(label="Converted Video") | |
gr.Markdown("### Download Converted Video") | |
file_download = gr.File(label="Download Video") | |
convert_button.click( | |
convert_video, | |
inputs=[use_youtube, youtube_url, video_file, downscale, faster, use_mp3, audio_only], | |
outputs=[video_preview, file_download] | |
) | |
demo.launch() |