import time import requests import subprocess import tempfile from pathlib import Path from moviepy.editor import VideoFileClip import gradio as gr def download_file(url, destination): """Downloads a file from a url to a destination.""" response = requests.get(url) response.raise_for_status() # Raises a HTTPError if the status is 4xx, 5xx with open(destination, 'wb') as f: f.write(response.content) def get_input_path(video_file, video_url, temp_dir): """Returns the path to the video file, downloading it if necessary.""" if video_file is not None: return video_file.name elif video_url: file_name = Path(video_url).name destination = temp_dir / file_name download_file(video_url, destination) return destination else: raise ValueError("No input was provided.") def get_output_path(input_path, temp_dir): """Returns the path to the output file, creating it if necessary.""" output_path = temp_dir / (input_path.stem + ".m3u8") return output_path def get_aspect_ratio(input_path, aspect_ratio): """Returns the aspect ratio of the video, calculating it if necessary.""" if aspect_ratio is not None: return aspect_ratio video = VideoFileClip(str(input_path)) return f"{video.size[0]}:{video.size[1]}" def convert_video(video_file, quality, aspect_ratio, video_url): """Converts a video to HLS format, adjusting the quality and aspect ratio as necessary.""" temp_dir = Path(tempfile.mkdtemp()) input_path = get_input_path(video_file, video_url, temp_dir) output_path = get_output_path(input_path, temp_dir) aspect_ratio = get_aspect_ratio(input_path, aspect_ratio) if not output_path.exists(): ffmpeg_command = ( f"ffmpeg -i {input_path} -c:v libx264 -crf {quality} " f"-vf scale=-1:720,setsar={aspect_ratio} -hls_time 6 " f"-hls_playlist_type vod -f hls {output_path}" ) try: subprocess.run(ffmpeg_command, shell=True, timeout=600) except subprocess.TimeoutExpired: return "ffmpeg command timed out." except FileNotFoundError: return "ffmpeg is not installed." except Exception as e: return f"An error occurred: {str(e)}" return output_path def main(): video_file = gr.inputs.File(label="Video File", type="file") quality = gr.inputs.Dropdown( choices=["18", "23", "28", "32"], label="Quality", default="23") aspect_ratio = gr.inputs.Dropdown( choices=[None, "1:1", "4:3", "3:2", "5:4", "16:9", "21:9", "1.85:1", "2.35:1", "3:1", "360", "9:16", "16:9", "2:1", "1:2", "9:1"], label="Aspect Ratio", default=None) video_url = gr.inputs.Textbox(label="Video URL") gr.Interface(convert_video, inputs=[video_file, quality, aspect_ratio, video_url], outputs='file').launch() if __name__ == "__main__": main()