eienmojiki's picture
Update app.py
964f774 verified
raw
history blame
4.29 kB
import gradio as gr
import subprocess
import os
#import spaces
def get_file_size(file_path):
"""Get file size in a human-readable format"""
if not file_path or not os.path.exists(file_path):
return "N/A"
size_bytes = os.path.getsize(file_path)
# Convert to appropriate unit
for unit in ['B', 'KB', 'MB', 'GB']:
if size_bytes < 1024 or unit == 'GB':
return f"{size_bytes:.2f} {unit}"
size_bytes /= 1024
#@spaces.GPU(duration=120)
def compress_video(video_file):
"""Compresses the uploaded video using FFmpeg and returns the output video path and file sizes."""
if video_file is None:
gr.Info("No video uploaded")
return None, "N/A", "N/A", 0
try:
# Get the input file path and size
input_path = video_file
input_size = get_file_size(input_path)
# Create output filename - in the same directory as input
base_dir = os.path.dirname(input_path)
filename = os.path.basename(input_path)
name, ext = os.path.splitext(filename)
output_path = os.path.join(base_dir, f"{name}_compressed{ext}")
# Execute ffmpeg command
command = [
"ffmpeg",
#"-hwaccel",
#"cuda",
"-i", input_path,
"-vcodec", "libx264",
"-crf", "28",
"-vf", "pad=ceil(iw/2)*2:ceil(ih/2)*2",
"-y",
output_path
]
# Show processing notification
gr.Info("Processing video...")
# Run the command
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout, stderr = process.communicate()
if process.returncode != 0:
error_message = stderr.decode()
gr.Info(f"Error: FFmpeg operation failed. Error message: {error_message}")
return None, input_size, "N/A", 0
# Calculate output size and savings
output_size = get_file_size(output_path)
# Calculate compression percentage
input_bytes = os.path.getsize(input_path)
output_bytes = os.path.getsize(output_path)
if input_bytes > 0:
compression_percent = (1 - (output_bytes / input_bytes)) * 100
else:
compression_percent = 0
# Show success notification
gr.Info(f"Video compressed successfully! Saved {compression_percent:.1f}% of original size")
# Return the processed video file and size information
return output_path, input_size, output_size, round(compression_percent, 1)
except Exception as e:
gr.Info(f"An error occurred: {str(e)}")
return None, get_file_size(video_file) if video_file else "N/A", "N/A", 0
with gr.Blocks(theme=gr.themes.Soft()) as app:
gr.Markdown("# Video Compression with FFmpeg")
gr.Markdown("""
- Uses H.264 codec
- CRF 28 (higher values = more compression, lower quality)
- Pads dimensions to ensure they're even numbers (required by some codecs)
Thanks for [this article](https://huggingface.co/posts/luigi12345/403914274386316) for providing the formula
""")
with gr.Row():
with gr.Column():
input_video = gr.Video(label="Upload Video")
input_size_display = gr.Textbox(label="Input File Size", interactive=False)
compress_btn = gr.Button("Compress Video", variant="primary")
with gr.Column():
output_video = gr.Video(label="Compressed Video")
output_size_display = gr.Textbox(label="Output File Size", interactive=False)
compression_ratio = gr.Number(label="Space Saved (%)", interactive=False)
compress_btn.click(
fn=compress_video,
inputs=[input_video],
outputs=[output_video, input_size_display, output_size_display, compression_ratio]
)
# Also update input size when video is uploaded
input_video.change(
fn=lambda video: get_file_size(video) if video else "N/A",
inputs=[input_video],
outputs=[input_size_display]
)
app.launch(debug=True, show_error=True)