Jeffgold's picture
Update app.py
065d626
raw
history blame
4.46 kB
import logging
import requests
from urllib.parse import urlparse
import subprocess
from pathlib import Path
from moviepy.editor import VideoFileClip
import gradio as gr
from gradio import components
# Define output directory
output_dir = Path.cwd() / "output"
output_dir.mkdir(exist_ok=True)
logging.basicConfig(level=logging.INFO)
def download_file(url, destination):
response = requests.get(url)
response.raise_for_status()
with open(destination, 'wb') as f:
f.write(response.content)
def get_input_path(video_file, video_url):
if video_file is not None:
return Path(video_file.name)
elif video_url:
url_path = urlparse(video_url).path
file_name = Path(url_path).name
destination = output_dir / file_name
download_file(video_url, destination)
return destination
else:
raise ValueError("No input was provided.")
def get_output_path(input_path, res):
output_path = output_dir / (Path(input_path).stem + f"_{res}.m3u8")
return output_path
def get_aspect_ratio(input_path, aspect_ratio):
if aspect_ratio is not None:
return aspect_ratio
video = VideoFileClip(str(input_path))
return f"{video.size[0]}:{video.size[1]}"
def create_master_playlist(output_paths):
master_playlist_path = output_dir / "master_playlist.m3u8"
with open(master_playlist_path, 'w') as f:
f.write("#EXTM3U\n")
for path in output_paths:
f.write(f"#EXT-X-STREAM-INF:BANDWIDTH={1000*1000},RESOLUTION={path.stem.split('_')[-1]}\n")
f.write(f"{path.name}\n")
return master_playlist_path
def convert_video(video_file, quality, aspect_ratio, video_url):
input_path = get_input_path(video_file, video_url)
aspect_ratio = get_aspect_ratio(input_path, aspect_ratio)
video = VideoFileClip(str(input_path))
original_height = video.size[1]
output_paths = []
for res in standard_resolutions:
if res > original_height:
continue
scale = "-1:" + str(res)
output_path = get_output_path(input_path, str(res) + 'p')
ffmpeg_command = [
"ffmpeg", "-i", str(input_path), "-c:v", "libx264", "-crf", str(quality),
"-vf", f"scale={scale}:force_original_aspect_ratio=decrease,pad=ceil(iw/2)*2:ceil(ih/2)*2",
"-hls_time", "10", "-hls_playlist_type", "vod", "-hls_segment_filename",
str(output_dir / f"{output_path.stem}_%03d.ts"), str(output_path)
]
logging.info("Running ffmpeg command: " + ' '.join(ffmpeg_command))
subprocess.run(ffmpeg_command, check=True)
output_paths.append(output_path)
master_playlist_path = create_master_playlist(output_paths)
output_paths.append(master_playlist_path)
# After generating the video files, return paths to them
output_files = [str(path) for path in output_paths]
return output_files
# Change "video" to "file"
video_file = gr.inputs.File(label="Your video file") # Remove `type="video"`
html_blocks = []
for path in output_paths:
video_path = f'http://localhost:5000/files/{path.name}'
video_component = f'''
<div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 10px;">
<video controls>
<source src="{video_path}" type="application/x-mpegURL">
Your browser does not support the video tag.
</video>
<p>
<a href="{video_path}" target="_blank">Download {path.stem}</a>
</p>
<p>Resolution: {path.stem.split('_')[-1]}</p>
</div>
'''
html_blocks.append(video_component)
return html_string
video_file = components.File(type="video", label="Your video file")
quality = components.Radio(["Low", "Medium", "High"], label="Quality", default="High")
aspect_ratio = components.Radio(["16:9", "4:3", "1:1"], label="Aspect Ratio", default="16:9")
video_url = components.Textbox(placeholder="or paste video url here", label="Video URL")
interface = gr.Interface(
fn=convert_video,
inputs=[video_file, quality, aspect_ratio, video_url],
outputs=gr.outputs.Video(label="Download Links"), # Changed to gr.outputs.Video
title="Video Converter",
description="A simple video converter app",
allow_flagging=False # Updated to False
)
interface.launch(server_name="0.0.0.0", server_port=7860)