File size: 3,763 Bytes
c16a803
 
 
07853df
6312c58
 
 
639e395
a56389b
065d626
6312c58
 
 
c16a803
40446f2
7028765
b8ab1d1
 
 
 
 
7028765
6c154f8
 
c16a803
6c154f8
 
79683ca
07853df
79683ca
c047e75
e4ed31e
cbd85fc
 
6312c58
6c154f8
 
 
 
3c753ee
07853df
6312c58
6c154f8
79683ca
6c154f8
 
 
 
 
6f1f7b0
07853df
6312c58
30f78b0
 
 
 
 
6312c58
30f78b0
1229389
07853df
f34662a
5a36eaa
f34662a
 
0212a08
2d3ac4b
e280197
1794bc0
 
 
bd750f5
2d3ac4b
 
5a36eaa
1794bc0
b8ab1d1
1794bc0
 
6312c58
1794bc0
30f78b0
1794bc0
 
1229389
2d3ac4b
1229389
07853df
1794bc0
30f78b0
065d626
 
 
 
 
 
7028765
 
 
a927b02
6c154f8
68299e3
 
6312c58
7028765
68299e3
 
7028765
1229389
99535b7
6312c58
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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)

standard_resolutions = [240, 360, 480, 720, 1080, 1440, 2160, 4320]
quality_mapping = {
    "Low": 35,
    "Medium": 23,
    "High": 18,
}

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_mapping[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"
quality = gr.inputs.Radio(["Low", "Medium", "High"], label="Quality", default="High")
aspect_ratio = gr.inputs.Radio(["16:9", "4:3", "1:1"], label="Aspect Ratio", default="16:9")
video_url = gr.inputs.Textbox(placeholder="or paste video url here", label="Video URL")
video_file = components.File(label="Your video file")

interface = gr.Interface(
    fn=convert_video, 
    inputs=[video_file, quality, aspect_ratio, video_url],
    outputs=gr.outputs.Textbox(label="Paths to Output Files"),
    title="Video Converter",
    description="A simple video converter app",
    allow_flagging=False
)

interface.launch(server_name="0.0.0.0", server_port=7860)