File size: 10,066 Bytes
96618f0
512ddf3
96618f0
 
 
b622a80
96618f0
 
 
 
61c73b3
 
96618f0
 
 
 
 
f8bfdd5
96618f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc9b4e1
9bed4cf
96618f0
 
512ddf3
 
1dc060a
512ddf3
4283596
512ddf3
4283596
512ddf3
 
 
 
 
96618f0
512ddf3
 
 
 
 
 
 
96618f0
14ce0dd
96618f0
 
512ddf3
 
 
 
 
 
 
96618f0
268c98c
96618f0
d601a16
512ddf3
 
 
 
 
 
 
9fd40c2
268c98c
d601a16
0c3bab8
b82f7ba
0a0b580
980b51d
7fa9c57
 
 
 
b82f7ba
 
9bed4cf
96618f0
 
 
 
 
 
 
d601a16
 
b880f48
512ddf3
96618f0
 
d601a16
 
f8bfdd5
d601a16
96618f0
 
 
 
 
 
 
d601a16
 
b880f48
96618f0
 
d601a16
 
c7ac3f3
d601a16
 
 
 
 
 
 
 
 
9fd40c2
b880f48
c7ac3f3
d601a16
96618f0
 
 
f45a615
96618f0
 
 
61c73b3
 
 
 
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import os
from ffmpy import FFmpeg, FFprobe
import gradio as gr
import subprocess
import shortuuid
import re
from tempfile import _TemporaryFileWrapper

# Check Runtime to avoid Error
globalopt = []
limit = os.getenv("SYSTEM") == "spaces"
if limit:
    globalopt = ["-y", "-hide_banner", "-threads 64", "-filter_threads 64", "-filter_complex_threads 64"]
else:
    globalopt = ["-y", "-hide_banner", "-hwaccel cuda", "-threads 64", "-filter_threads 64", "-filter_complex_threads 64"]

# Function to process data
def convert(file: _TemporaryFileWrapper, options: str):
    output_file=""
    video=""
    stdout=""
    ffmpeg=FFmpeg()
    print(file)
    print(options)
    try:
        output_file = f"{shortuuid.ShortUUID().random(length=8)}.mp4"
        ffmpeg = FFmpeg(inputs={file: None}, outputs={output_file: f"{options}"}, global_options=globalopt)
        ffmpeg.run(stderr=subprocess.PIPE)
        # pprint(f"{stdout} {stderr}")
        stdout += f"{ffmpeg.cmd}"
        gr.Textbox.update(value=stdout)
        gr.Video.update(value=output_file)

    except Exception as e:
        stdout += f"{e}"
        gr.exceptions.Error(stdout)
    return [stdout, output_file]

# Check Video Codec
def chk_cod(a):
    command = f"ffprobe \"{a}\" 2>&1 >/dev/null"
    output = subprocess.check_output(command, shell=True).decode("utf-8")
    print(output)
    match = re.search(r"Stream.*Video.*", output)
    print(match)
    if match:
        video_info = match.group()
        codec = re.sub(r".*Video: ([^, ]+).*", r"\1", video_info)
        return codec
    
# Command Builder: Smooth Interpolation
def cmdb_si(a, b, c, d):
    # Check Input Video Codec
    cod = chk_cod(d)
    if cod == "h264":
        tuning = f"-tune {c.split(' –')[0]}"
    else:
        tuning = ""
    # print(tuning)
    return f"-filter:v \"minterpolate='mi_mode=mci:mc_mode=aobmc:me_mode=bidir:vsbmc=1:fps={a}'\" -r {a} -preset {b} {tuning}"

# Command Builder: Frame Blending
def cmdb_fb(a, b, c, d):
    # Check Input Video Codec
    cod = chk_cod(d)
    if cod == "h264":
        tuning = f"-tune {c.split(' –')[0]}"
    else:
        tuning = ""
    # print(tuning)
    return f"-filter:v \"tblend\" -r {a} -preset {b} {tuning}"

# Command Builder: Advanced
def cmdb_adv(a, b, c):
    # Check Input Video Codec
    cod = chk_cod(c)
    if cod == "h264":
        tuning = f"-tune {b.split(' –')[0]}"
    else:
        tuning = ""
    #gr.Textbox.update(value=f"-preset {a} -tune {b}")
    return f"-preset {a} {tuning}"

with gr.Blocks(title="FFmo - FFmpeg Online", theme=gr.themes.Soft()) as main:
    gr.Markdown(
        "# <center> FFmo - FFmpeg Online </center>\n"
        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1BWgdzhL118O6fENqYCIIG9WgCfiTkQ65?usp=share_link)\n\n"
        "## Feature Description:\n"
        "- Smooth Interpolation – Smooth interpolation is a technique used in video filtering to enhance the visual quality and smoothness of video sequences. It involves estimating the values of pixels or frames between existing frames in order to create seamless transitions and reduce jerkiness or flickering.\n"
        "- Frame Blending – \"Frame blending\" is a video filtering technique used to create smooth transitions between frames in a video sequence. It involves blending two or more adjacent frames together to generate intermediate frames, resulting in a smoother appearance during playback.\n"
        "- Advanced – For Professional/Developer Only. It only Include **Tuning** section only.\n\n"
        "### NOTE: \"Tuning\" option is not supported if the input video codec is other than \"H.264\"\n"
    )
    gr.exceptions.Warning("Jangan Lupa Untuk Memilih Preset & Tune ya!")
    with gr.Tabs():
        with gr.TabItem("Smooth Interpolation"):
            with gr.Row():
                with gr.Column() as inp_si:
                    input_fps = gr.Slider(1, 144, value=60, label="Frame Per Second (FPS)", info="Choose between 1 and 144 Fps")
                    input_preset = gr.Dropdown(["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow"], value=["veryslow"], label="Preset (Required)", info="Semakin lama (slow), semakin bagus hasilnya.")
                    input_tune = gr.Radio(["film – use for high quality movie content; lowers deblocking", "animation – good for cartoons; uses higher deblocking and more reference frames", "grain – preserves the grain structure in old, grainy film material", "stillimage – good for slideshow-like content", "fastdecode – allows faster decoding by disabling certain filters", "zerolatency – good for fast encoding and low-latency streaming", "psnr – ignore this as it is only used for codec development", "ssim – ignore this as it is only used for codec development"], value=["film – use for high quality movie content; lowers deblocking"], label="Tune (Required)", info="Tuning Setting")
                    input_video = gr.Video(label="Input Video")
                    input_textbox = gr.Textbox(label="FFMPEG Command")
                    buildcmd = gr.Button("Build FFMPEG Command", variant="primary").click(fn=cmdb_si, inputs=[input_fps,input_preset,input_tune,input_video], outputs=[input_textbox])
                    # input_video.change()

                with gr.Column() as out_si:
                    output_textbox = gr.Textbox(label="Output Logs", interactive=False)
                    output_video = gr.Video(label="Output Video", interactive=False)
                startconv = gr.Button("Start", variant="primary").click(fn=convert, inputs=[input_video,input_textbox], outputs=[output_textbox, output_video])
                clear_button = gr.ClearButton([input_fps, input_preset, input_tune, input_video, input_textbox, output_textbox, output_video])
        
        with gr.TabItem("Frame Blending"):
            with gr.Row():
                with gr.Column() as inp_fb:
                    input_fps2 = gr.Slider(1, 144, value=60, label="Frame Per Second (FPS)", info="Choose between 1 and 144 Fps")
                    input_preset2 = gr.Dropdown(["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow"], value=["veryslow"], label="Preset (Required)", info="Semakin lama (slow), semakin bagus hasilnya.")
                    input_tune2 = gr.Radio(["film – use for high quality movie content; lowers deblocking", "animation – good for cartoons; uses higher deblocking and more reference frames", "grain – preserves the grain structure in old, grainy film material", "stillimage – good for slideshow-like content", "fastdecode – allows faster decoding by disabling certain filters", "zerolatency – good for fast encoding and low-latency streaming", "psnr – ignore this as it is only used for codec development", "ssim – ignore this as it is only used for codec development"], value=["film – use for high quality movie content; lowers deblocking"], label="Tune (Required)", info="Tuning Setting")
                    input_video2 = gr.Video(label="Input Video")
                    input_textbox2 = gr.Textbox(label="FFMPEG Command")
                    buildcmd2 = gr.Button("Build FFMPEG Command", variant="primary").click(fn=cmdb_fb, inputs=[input_fps2,input_preset2,input_tune2, input_video2], outputs=[input_textbox2])

                with gr.Column() as out_fb:
                    output_textbox2 = gr.Textbox(label="Output Logs", interactive=False)
                    output_video2 = gr.Video(label="Output Video", interactive=False)
 
                startconv2 = gr.Button("Start", variant="primary").click(fn=convert, inputs=[input_video2,input_textbox2], outputs=[output_textbox2, output_video2])
                clear_button2 = gr.ClearButton([input_fps2, input_preset2, input_tune2, input_video2, input_textbox2, output_textbox2, output_video2])

        with gr.TabItem("Advanced"):
            with gr.Row():
                with gr.Column() as inp_main:
                    input_preset3 = gr.Dropdown(["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow"], value=["veryslow"], label="Preset (Required)", info="Semakin lama (slow), semakin bagus hasilnya.")
                    input_tune3 = gr.Radio(["film – use for high quality movie content; lowers deblocking", "animation – good for cartoons; uses higher deblocking and more reference frames", "grain – preserves the grain structure in old, grainy film material", "stillimage – good for slideshow-like content", "fastdecode – allows faster decoding by disabling certain filters", "zerolatency – good for fast encoding and low-latency streaming", "psnr – ignore this as it is only used for codec development", "ssim – ignore this as it is only used for codec development"], value=["film – use for high quality movie content; lowers deblocking"], label="Tune (Required)", info="Tuning Setting")
                    input_video3 = gr.Video(label="Input Video")
                    input_textbox3 = gr.Textbox(label="FFMPEG Command")
                    buildcmd3 = gr.Button("Build FFMPEG Command", variant="primary").click(fn=cmdb_adv, inputs=[input_preset3,input_tune3, input_video3], outputs=[input_textbox3])

                with gr.Column() as out_main:
                    output_textbox3 = gr.Textbox(label="Output Logs", interactive=False)
                    output_video3 = gr.Video(label="Output Video", interactive=False)
                startconv3 = gr.Button("Start", variant="primary").click(fn=convert, inputs=[input_video3,input_textbox3], outputs=[output_textbox3, output_video3])
                clear_button3 = gr.ClearButton([input_tune3, input_preset3, input_textbox3, input_video3, output_textbox3, output_video3])

# Launch the combined interface
if __name__ == "__main__":
    if limit:
        main.queue(concurrency_count=5).launch()
    else:
        main.queue(concurrency_count=5).launch(debug=True, share=True)