File size: 3,071 Bytes
485608a
79683ca
faa2bdb
5296733
40446f2
e4ed31e
6c154f8
40446f2
6c154f8
 
 
 
 
 
79683ca
cbd85fc
 
6c154f8
 
79683ca
c047e75
e4ed31e
cbd85fc
 
6c154f8
 
 
 
 
3c753ee
c047e75
6c154f8
 
 
 
79683ca
6c154f8
 
 
 
 
 
6f1f7b0
6c154f8
 
 
 
 
 
6f1f7b0
6c154f8
 
 
 
 
 
 
 
 
b7e494d
 
 
 
6c154f8
 
 
 
 
 
 
 
52cd85c
6c154f8
 
 
 
 
 
b7e494d
6c154f8
b7e494d
6c154f8
 
0dcabf9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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)

from urllib.parse import urlparse

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 Path(video_file.name)
    elif video_url:
        url_path = urlparse(video_url).path
        file_name = Path(url_path).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()