reab5555's picture
Upload 2 files
e25fed3 verified
import gradio as gr
import os
from pathlib import Path
from datetime import datetime
from converter_fw import VideoConverter
import tempfile
import shutil
class VideoConverterGUI:
def __init__(self):
self.converter = VideoConverter()
self.current_progress = 0
self.status_message = ""
self.output_dir = os.path.join(os.getcwd(), "converted_videos")
os.makedirs(self.output_dir, exist_ok=True)
# Define video extensions
self.video_extensions = [
".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".mpeg",
".MP4", ".AVI", ".MKV", ".MOV", ".WMV", ".FLV", ".MPEG"
]
def generate_output_filename(self, input_filename, output_format):
name = Path(input_filename).stem
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
return f"{name}_{timestamp}.{output_format.lower()}"
def update_video_display(self, files):
"""Update the video preview"""
if not files or len(files) == 0:
return None
return files[0]
def create_temp_copy(self, file_path):
"""Create a temporary copy of the input file"""
file_ext = os.path.splitext(file_path)[1]
temp_file = tempfile.NamedTemporaryFile(suffix=file_ext, delete=False)
temp_path = temp_file.name
temp_file.close()
shutil.copy2(file_path, temp_path)
return temp_path
def is_valid_video(self, file_path):
"""Check if file has a valid video extension"""
return any(file_path.lower().endswith(ext.lower()) for ext in self.video_extensions)
def convert_videos(self, files, output_format, codec, resolution, bitrate, bitrate_unit, fps, progress=gr.Progress()):
if not files:
return "Please upload video files.", []
results = []
output_files = []
temp_files = []
# Filter valid video files
valid_files = [f for f in files if self.is_valid_video(f.name)]
if not valid_files:
return "No valid video files found. Please upload video files.", []
total_files = len(valid_files)
file_weight = 1.0 / total_files
# Process bitrate input
if bitrate.strip().lower() != "auto" and bitrate.strip() != "":
try:
bitrate_value = float(bitrate)
if bitrate_unit == "kbps":
bitrate_value = f"{bitrate_value}k"
elif bitrate_unit == "Mbps":
bitrate_value = f"{bitrate_value}M"
else:
return "Invalid bitrate unit selected.", []
except ValueError:
return f"Invalid bitrate value: {bitrate}. Please enter a numeric value.", []
else:
bitrate_value = "auto"
try:
for i, file in enumerate(valid_files):
try:
base_progress = i * file_weight
# Create a temporary copy of the input file
temp_input_path = self.create_temp_copy(file.name)
temp_files.append(temp_input_path)
original_filename = os.path.basename(file.name)
progress(base_progress, desc=f"Converting {original_filename}")
def progress_callback(file_progress):
total_progress = base_progress + (file_progress * file_weight)
progress(total_progress)
output_filename = self.generate_output_filename(original_filename, output_format)
print(f"Converting {temp_input_path} to {output_filename}") # Debug print
success, message = self.converter.convert_video(
temp_input_path,
output_format,
codec,
self.output_dir,
progress_callback,
output_filename,
resolution,
bitrate_value,
fps
)
if success:
output_path = os.path.join(self.output_dir, output_filename)
if os.path.exists(output_path):
output_files.append(output_path)
results.append(message)
except Exception as e:
print(f"Detailed error for {file.name}: {str(e)}") # Debug print
results.append(f"Error processing {os.path.basename(file.name)}: {str(e)}")
finally:
# Clean up temporary files
for temp_file in temp_files:
try:
if os.path.exists(temp_file):
os.remove(temp_file)
except Exception as e:
print(f"Error cleaning up {temp_file}: {str(e)}")
success_count = sum(1 for msg in results if "Successfully" in msg)
report = f"Conversion completed: {success_count}/{total_files} files converted successfully\n\n"
report += "\n".join(results)
return report, output_files if output_files else None
def create_ui(self):
with gr.Blocks() as app:
gr.Markdown(f"""
# Batch Video Converter
GPU Acceleration: {"Available" if self.converter.gpu_available else "Not Available"}
""")
with gr.Column():
# Input Settings Section
gr.Markdown("### Input Settings")
with gr.Row():
with gr.Column(scale=1):
input_videos = gr.Files(
label="Upload Videos",
file_count="multiple",
file_types=["video"],
type="filepath"
)
with gr.Row():
preview = gr.Video(
label="Video Preview",
format="mp4",
visible=True,
interactive=False
)
# Conversion Settings Section
gr.Markdown("### Conversion Settings")
with gr.Row():
format_dropdown = gr.Dropdown(
choices=self.converter.formats,
value="MP4",
label="Output Format"
)
codec_dropdown = gr.Dropdown(
choices=self.converter.codecs,
value="H.264",
label="Codec"
)
# Add output resolution, bitrate, and fps options
with gr.Row():
resolution_dropdown = gr.Dropdown(
choices=[
"Same as input",
"3840x2160 (4K)",
"2560x1440 (1440p)",
"1920x1080 (1080p)",
"1280x720 (720p)",
"854x480 (480p)"
],
value="Same as input",
label="Output Resolution"
)
with gr.Row():
bitrate_input = gr.Textbox(
label="Output Bitrate",
placeholder="Enter value or leave blank for auto",
value=""
)
bitrate_unit = gr.Dropdown(
choices=["kbps", "Mbps"],
value="Mbps",
label="Bitrate Unit"
)
with gr.Row():
fps_dropdown = gr.Dropdown(
choices=[
"Same as input",
"23.97",
"24",
"25",
"29.97",
"30",
"60"
],
value="Same as input",
label="Output FPS"
)
# Conversion Button and Progress Section
convert_btn = gr.Button(
"Convert Videos",
variant="primary",
size="lg"
)
gr.Markdown("### Conversion Progress")
output_text = gr.Textbox(
label="Status",
lines=10,
show_copy_button=True
)
# Download Section
gr.Markdown("### Download Converted Videos")
output_files = gr.Files(
label="Converted Videos (Click to download)",
interactive=False
)
# Event handlers
input_videos.change(
fn=self.update_video_display,
inputs=[input_videos],
outputs=[preview]
)
convert_btn.click(
fn=self.convert_videos,
inputs=[
input_videos,
format_dropdown,
codec_dropdown,
resolution_dropdown,
bitrate_input,
bitrate_unit,
fps_dropdown
],
outputs=[
output_text,
output_files
]
)
return app
def main(self):
gui = VideoConverterGUI()
app = gui.create_ui()
app.launch()
if __name__ == "__main__":
VideoConverterGUI().main()