ismot Micrrosoft commited on
Commit
de816ec
·
0 Parent(s):

Duplicate from Micrrosoft/Media-Converter

Browse files

Co-authored-by: Microsoft <[email protected]>

Files changed (13) hide show
  1. .github/workflows/main.yml +27 -0
  2. .gitignore +5 -0
  3. README.md +47 -0
  4. app.py +174 -0
  5. codecs.json +25 -0
  6. data.json +1189 -0
  7. functions.py +515 -0
  8. images/gradio-app.png +0 -0
  9. mappings.json +62 -0
  10. new_mappings.json +68 -0
  11. output.json +46 -0
  12. requirements.txt +61 -0
  13. styles.css +9 -0
.github/workflows/main.yml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Sync to Hugging Face hub
2
+ on:
3
+ push:
4
+ branches: [main]
5
+
6
+ # to run this workflow manually from the Actions tab
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ sync-to-hub:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ with:
15
+ fetch-depth: 0
16
+ - name: Add remote
17
+ env:
18
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
19
+ HF_USERNAME: Accel
20
+ HF_SPACE: huggingface.co/spaces/Accel/media-converter
21
+ run: git remote add space https://$HF_USERNAME:$HF_TOKEN@$HF_SPACE
22
+ - name: Push to hub
23
+ env:
24
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
25
+ HF_USERNAME: Accel
26
+ HF_SPACE: huggingface.co/spaces/Accel/media-converter
27
+ run: git push --force https://$HF_USERNAME:$HF_TOKEN@$HF_SPACE main
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.pyc
3
+ flagged/
4
+ .venv
5
+ docs/
README.md ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: FFmpeg Media Converter
3
+ emoji: 💻
4
+ colorFrom: blue
5
+ colorTo: blue
6
+ sdk: gradio
7
+ sdk_version: 3.3.1
8
+ app_file: app.py
9
+ tags:
10
+ - ffmpeg
11
+ - converter
12
+ - media
13
+ - processing
14
+ pinned: false
15
+ license: mit
16
+ duplicated_from: Micrrosoft/Media-Converter
17
+ ---
18
+
19
+
20
+ Visit for more powerful tools www.aibeast.net
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+ # Overview
35
+ Simple gradio interface for ffmpeg filters and codecs
36
+
37
+ ![Content](./images/gradio-app.png)
38
+ ## Dev
39
+ Built with Gradio and ffmpy
40
+
41
+ inspiration by [ffmpeg-commander](https://www.github.com/alfg/ffmpeg-commander)
42
+ # Install
43
+ Clone the repo and
44
+ `pip install -r requirements.txt`
45
+ - To run locally
46
+
47
+ `gradio app.py`
app.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import subprocess
3
+ from pprint import pprint
4
+ from tempfile import _TemporaryFileWrapper
5
+
6
+ from ffmpy import FFmpeg
7
+
8
+ import gradio as gr
9
+ from functions import (Clear, CommandBuilder, audio_channels, audio_codecs,
10
+ audio_quality, audio_sample_rates,
11
+ change_clipbox, containers, customBitrate, mediaChange, presets, supported_codecs, supported_presets, video_codecs, video_containers,
12
+ vf)
13
+
14
+ logging.basicConfig(level=logging.INFO)
15
+
16
+ logging.info(msg=f"{video_containers}")
17
+
18
+
19
+ def convert(file: _TemporaryFileWrapper, options: str,state):
20
+ stderr=""
21
+ stdout=""
22
+ output_file=""
23
+ video=""
24
+ ffmpeg=FFmpeg()
25
+ try:
26
+ logging.info(f"File name: {file.name}")
27
+ new_name, _ = file.name.split(".")
28
+ logging.info(f"New filename:{new_name}")
29
+ output_file = f"{new_name}1.{options.lower()}"
30
+ ffmpeg = FFmpeg(inputs={file.name: None}, outputs={
31
+ output_file: ffmpeg_commands.commands.split()}, global_options=["-y", "-hide_banner"])
32
+ print(ffmpeg)
33
+ print(ffmpeg.cmd)
34
+
35
+ ffmpeg.run(stderr=subprocess.PIPE)
36
+ # pprint(f"{stdout} {stderr}")
37
+ output=f"{ffmpeg.cmd}"
38
+ # video=gr.update(label=output_file,value=output_file)
39
+
40
+ except Exception as e:
41
+ stderr=e
42
+ output=f"{stderr}"
43
+ return [None,None,None,output]
44
+
45
+ state=output_file
46
+
47
+ return [output_file,output_file,output_file,output,state]
48
+
49
+ title="##"
50
+
51
+ description="""
52
+ <p style="text-align:center;">
53
+ <br />You can visit for more powerful tools <a href="https://aibeast.net" target="_blank">AI Beast</a> and follow for updates <a href="https://www.facebook.com/abbas143office" target="_blank">Follow</a>
54
+ </p>
55
+ """
56
+
57
+ with gr.Blocks(css="./styles.css") as dm:
58
+ with gr.Tabs():
59
+ with gr.TabItem("Format"):
60
+ # Input Buttons
61
+ with gr.Row():
62
+ with gr.Column() as inputs:
63
+ file_input = gr.File()
64
+ options = gr.Radio(
65
+ label="options", choices=containers,value=containers[0])
66
+ with gr.Row():
67
+ with gr.Row() as inputs_clip:
68
+ clip = gr.Dropdown(
69
+ choices=["None", "Enabled"], label="Clip:", value="None")
70
+ start_time = gr.Textbox(
71
+ label="Start Time:", placeholder="00:00", visible=False,interactive=True)
72
+ stop_time = gr.Textbox(
73
+ label="Stop Time:", placeholder="00:00", visible=False)
74
+ with gr.Row():
75
+ clearBtn = gr.Button("Clear")
76
+ convertBtn = gr.Button("Convert", variant="primary")
77
+
78
+ # Output Buttons
79
+ with gr.Column():
80
+ # media_output = gr.Audio(label="Output")
81
+ with gr.Row():
82
+ video_button=gr.Button("Video")
83
+ audio_button=gr.Button("Audio")
84
+ file_button=gr.Button("File")
85
+ media_output_audio = gr.Audio(type="filepath",label="Output",visible=True,interactive=False,source="filepath")
86
+ media_output_video = gr.Video(label="Output",visible=False)
87
+ media_output_file = gr.File(label="Output",visible=False)
88
+ with gr.Row() as command_output:
89
+ output_textbox = gr.Textbox(label="command",elem_id="outputtext")
90
+
91
+ resetFormat=Clear(inputs,inputs_clip)
92
+ print(inputs_clip.children)
93
+ print(resetFormat)
94
+ state=gr.Variable()
95
+ clearBtn.click(resetFormat.clear, inputs=resetFormat(), outputs=resetFormat())
96
+ convertBtn.click(convert, inputs=[file_input, options,state], outputs=[
97
+ media_output_audio,media_output_file,media_output_video, output_textbox,state])
98
+
99
+ with gr.TabItem("Video"):
100
+ with gr.Row() as video_inputs:
101
+ video_options = gr.Dropdown(
102
+ label="video", choices=video_codecs,value=video_codecs[-1])
103
+ preset_options = gr.Dropdown(choices=presets, label="presets",value=presets[-1])
104
+
105
+
106
+ with gr.Row(elem_id="button"):
107
+ with gr.Column():
108
+ clearBtn = gr.Button("Clear")
109
+ videoReset=Clear(video_inputs)
110
+ clearBtn.click(videoReset.clear, videoReset(), videoReset())
111
+
112
+ with gr.TabItem("Audio"):
113
+ with gr.Row() as audio_inputs:
114
+ # print(names[0])
115
+ audio_options = gr.Dropdown(
116
+ label="audio", choices=audio_codecs, value=audio_codecs[-1])
117
+ audio_bitrate=gr.Dropdown(choices=audio_quality, label="Audio Qualities",
118
+ value=audio_quality[0])
119
+ custom_bitrate=gr.Number(label="Audio Qualities",visible=False)
120
+ gr.Dropdown(choices=audio_channels,
121
+ label="Audio Channels", value=audio_channels[0])
122
+ gr.Dropdown(choices=audio_sample_rates,
123
+ label="Sample Rates", value=audio_sample_rates[0])
124
+
125
+
126
+ with gr.Column(elem_id="button"):
127
+ clearBtn = gr.Button("Clear")
128
+ audioReset=Clear(audio_inputs)
129
+ clearBtn.click(audioReset.clear, audioReset(), audioReset())
130
+
131
+ with gr.TabItem("Filters") as filter_inputs:
132
+ gr.Markdown("## Video")
133
+ with gr.Row().style(equal_height=True) as filter_inputs:
134
+ for i in vf:
135
+ # print(i.values())
136
+ # values = list(i.values())
137
+ values=list(i.values())[0]
138
+ choices=[j for lst in values for j in [lst.get("name")]]
139
+ a=gr.Dropdown(label=list(i.keys()),
140
+ choices=choices, value=choices[0])
141
+ gr.Markdown("## Audio")
142
+ with gr.Row(elem_id="acontrast") as filter_inputs_1:
143
+ acontrastSlider=gr.Slider(label="Acontrast", elem_id="acontrast")
144
+
145
+ with gr.Column(elem_id="button"):
146
+ clearBtn = gr.Button("Clear")
147
+
148
+ filterReset=Clear(filter_inputs,filter_inputs_1)
149
+ clearBtn.click(filterReset.clear, filterReset(), filterReset())
150
+
151
+ """ Format Tab change functions"""
152
+ ffmpeg_commands=CommandBuilder(inputs_clip,video_inputs,audio_inputs,filter_inputs,filter_inputs_1)
153
+ # ffmpeg_commands.do()
154
+ dm.load(fn=ffmpeg_commands.reset,inputs=[],outputs=[])
155
+ pprint(ffmpeg_commands.commands)
156
+ ffmpeg_commands.update(output_textbox)
157
+ # file_input.change(fn=updateOutput,inputs=file_input,outputs=output_textbox)
158
+ clip.change(fn=change_clipbox, inputs=clip,
159
+ outputs=[start_time, stop_time])
160
+
161
+ options.change(supported_codecs,[options],[video_options,audio_options])
162
+ # options.change(mediaChange,[options],[media_output_audio,media_output_video])
163
+ # video_button.click(fn=videoChange,inputs=media_output_file,outputs=media_output_video)
164
+ audio_button.click(mediaChange,[audio_button,state],[media_output_audio,media_output_video,media_output_file])
165
+ video_button.click(mediaChange,[video_button,state],[media_output_audio,media_output_video,media_output_file])
166
+ # media_output_audio.change(lambda x:gr.update(value=x),[media_output_audio],[media_output_video])
167
+ file_button.click(mediaChange,[file_button,state],[media_output_audio,media_output_video,media_output_file])
168
+ """Video Tab change functions"""
169
+ video_options.change(supported_presets,[video_options],[preset_options])
170
+ """Audio Tab change functions"""
171
+ audio_bitrate.change(customBitrate,[audio_bitrate],[custom_bitrate])
172
+
173
+ if __name__=='__main__':
174
+ dm.launch()
codecs.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "video": {
3
+ "x264": "libx264",
4
+ "x265": "libx265",
5
+ "h264_nvenc": "h264_nvenc",
6
+ "hevc_nvenc": "hevc_nvenc",
7
+ "vp8": "libvpx",
8
+ "vp9": "libvpx-vp9",
9
+ "av1": "libaom-av1",
10
+ "mpeg2": "mpeg2video",
11
+ "mpeg4": "mpeg4 -vtag xvid",
12
+ "theora": "libtheora"
13
+ },
14
+ "audio": {
15
+ "aac": "aac",
16
+ "alac": "alac",
17
+ "dts": "dca",
18
+ "ac3": "ac3",
19
+ "vorbis": "libvorbis",
20
+ "opus": "libopus",
21
+ "lame":"libmp3lame",
22
+ "pcm":"pcm_s16le"
23
+ },
24
+ "copy": "copy"
25
+ }
data.json ADDED
@@ -0,0 +1,1189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "protocols": [
3
+ {
4
+ "name": "File",
5
+ "value": "movie.mp4"
6
+ },
7
+ {
8
+ "name": "FTP",
9
+ "value": "ftp://[user[:password]@]server[:port]/path/to/remote/movie.mp4"
10
+ },
11
+ {
12
+ "name": "HTTP",
13
+ "value": "http://server:port/movie.mp4"
14
+ },
15
+ {
16
+ "name": "HTTPS",
17
+ "value": "https://server:port/movie.mp4"
18
+ },
19
+ {
20
+ "name": "RTMP",
21
+ "value": "rtmp://[username:password@]server[:port][/app][/instance][/playpath]"
22
+ },
23
+ {
24
+ "name": "SRT",
25
+ "value": "srt://hostname:port[?options]"
26
+ },
27
+ {
28
+ "name": "TCP",
29
+ "value": "tcp://hostname:port[?options]"
30
+ },
31
+ {
32
+ "name": "UDP",
33
+ "value": "udp://hostname:port[?options]"
34
+ }
35
+ ],
36
+ "containers": {
37
+ "video": [
38
+ {
39
+ "name": "MP4",
40
+ "value": "mp4"
41
+ },
42
+ {
43
+ "name": "MKV",
44
+ "value": "mkv"
45
+ },
46
+ {
47
+ "name": "WebM",
48
+ "value": "webm"
49
+ },
50
+ {
51
+ "name": "MPG",
52
+ "value": "mpg"
53
+ },
54
+ {
55
+ "name": "AVI",
56
+ "value": "avi"
57
+ },
58
+ {
59
+ "name": "OGV",
60
+ "value": "ogv"
61
+ },
62
+ {
63
+ "name": "FLV",
64
+ "value": "flv"
65
+ }
66
+ ],
67
+ "audio": [
68
+ {
69
+ "name": "MP3",
70
+ "value": "mp3"
71
+ },
72
+ {
73
+ "name": "M4A",
74
+ "value": "m4a"
75
+ },
76
+ {
77
+ "name": "OGG",
78
+ "value": "ogg"
79
+ },
80
+ {
81
+ "name": "FLAC",
82
+ "value": "flac"
83
+ },
84
+ {
85
+ "name": "WAV",
86
+ "value": "wav"
87
+ }
88
+ ]
89
+ },
90
+ "clip": [
91
+ {
92
+ "name": "None",
93
+ "value": false
94
+ },
95
+ {
96
+ "name": "Enabled",
97
+ "value": true
98
+ }
99
+ ],
100
+ "codecs": {
101
+ "video": [
102
+ {
103
+ "name": "x264",
104
+ "value": "x264",
105
+ "supported": [
106
+ "mp4",
107
+ "mkv",
108
+ "avi"
109
+ ]
110
+ },
111
+ {
112
+ "name": "x265",
113
+ "value": "x265",
114
+ "supported": [
115
+ "mp4",
116
+ "mkv",
117
+ "avi"
118
+ ]
119
+ },
120
+ {
121
+ "name": "h264_nvenc (Nvidia NVENC)",
122
+ "value": "h264_nvenc",
123
+ "supported": [
124
+ "mp4"
125
+ ]
126
+ },
127
+ {
128
+ "name": "hevc_nvenc (Nvidia NVENC)",
129
+ "value": "hevc_nvenc",
130
+ "supported": [
131
+ "mp4"
132
+ ]
133
+ },
134
+ {
135
+ "name": "AV1",
136
+ "value": "av1",
137
+ "supported": [
138
+ "mp4",
139
+ "mkv"
140
+ ]
141
+ },
142
+ {
143
+ "name": "VP8",
144
+ "value": "vp8",
145
+ "supported": [
146
+ "mp4",
147
+ "webm",
148
+ "mkv",
149
+ "avi"
150
+ ]
151
+ },
152
+ {
153
+ "name": "VP9",
154
+ "value": "vp9",
155
+ "supported": [
156
+ "mp4",
157
+ "webm",
158
+ "mkv",
159
+ "avi"
160
+ ]
161
+ },
162
+ {
163
+ "name": "copy",
164
+ "value": "copy",
165
+ "supported": null
166
+ }
167
+ ],
168
+ "audio": [
169
+ {
170
+ "name": "AAC",
171
+ "value": "aac",
172
+ "supported": [
173
+ "mp4",
174
+ "mp3",
175
+ "m4a",
176
+ "mkv",
177
+ "avi",
178
+ "flv"
179
+ ]
180
+ },
181
+ {
182
+ "name": "AC3",
183
+ "value": "ac3",
184
+ "supported": [
185
+ "mp4",
186
+ "mkv",
187
+ "avi"
188
+ ]
189
+ },
190
+ {
191
+ "name": "DTS",
192
+ "value": "dts",
193
+ "supported": [
194
+ "mp4",
195
+ "mkv",
196
+ "avi"
197
+ ]
198
+ },
199
+ {
200
+ "name": "Vorbis",
201
+ "value": "vorbis",
202
+ "supported": [
203
+ "mp4",
204
+ "mkv",
205
+ "ogg",
206
+ "webm"
207
+ ]
208
+ },
209
+ {
210
+ "name": "Opus",
211
+ "value": "opus",
212
+ "supported": [
213
+ "mp4",
214
+ "mkv",
215
+ "ogg",
216
+ "webm"
217
+ ]
218
+ },
219
+ {
220
+ "name": "LAME",
221
+ "value": "lame",
222
+ "supported": [
223
+ "mp3",
224
+ "mkv"
225
+ ]
226
+ },
227
+ {
228
+ "name": "ALAC",
229
+ "value": "alac",
230
+ "supported": [
231
+ "mp4",
232
+ "mkv",
233
+ "m4a",
234
+ "avi"
235
+ ]
236
+ },
237
+ {
238
+ "name": "FLAC",
239
+ "value": "flac",
240
+ "supported": [
241
+ "flac",
242
+ "mkv",
243
+ "avi"
244
+ ]
245
+ },
246
+ {
247
+ "name": "PCM",
248
+ "value": "pcm",
249
+ "supported": [
250
+ "mkv"
251
+ ]
252
+ },
253
+ {
254
+ "name": "Copy",
255
+ "value": "copy",
256
+ "supported": null
257
+ },
258
+ {
259
+ "name": "None",
260
+ "value": "none",
261
+ "supported": null
262
+ }
263
+ ]
264
+ },
265
+ "presets": [
266
+ {
267
+ "name": "Placebo",
268
+ "value": "placebo",
269
+ "supported": [
270
+ "x264",
271
+ "x265"
272
+ ]
273
+ },
274
+ {
275
+ "name": "Very Slow",
276
+ "value": "veryslow",
277
+ "supported": [
278
+ "x264",
279
+ "x265"
280
+ ]
281
+ },
282
+ {
283
+ "name": "Slower",
284
+ "value": "slower",
285
+ "supported": [
286
+ "x264",
287
+ "x265"
288
+ ]
289
+ },
290
+ {
291
+ "name": "Slow",
292
+ "value": "slow",
293
+ "supported": [
294
+ "x264",
295
+ "x265",
296
+ "h264_nvenc",
297
+ "hevc_nvenc"
298
+ ]
299
+ },
300
+ {
301
+ "name": "Medium",
302
+ "value": "medium",
303
+ "supported": [
304
+ "x264",
305
+ "x265",
306
+ "h264_nvenc",
307
+ "hevc_nvenc"
308
+ ]
309
+ },
310
+ {
311
+ "name": "Fast",
312
+ "value": "fast",
313
+ "supported": [
314
+ "x264",
315
+ "x265",
316
+ "h264_nvenc",
317
+ "hevc_nvenc"
318
+ ]
319
+ },
320
+ {
321
+ "name": "Faster",
322
+ "value": "faster",
323
+ "supported": [
324
+ "x264",
325
+ "x265"
326
+ ]
327
+ },
328
+ {
329
+ "name": "Very Fast",
330
+ "value": "veryfast",
331
+ "supported": [
332
+ "x264",
333
+ "x265"
334
+ ]
335
+ },
336
+ {
337
+ "name": "Super Fast",
338
+ "value": "superfast",
339
+ "supported": [
340
+ "x264",
341
+ "x265"
342
+ ]
343
+ },
344
+ {
345
+ "name": "Ultra Fast",
346
+ "value": "ultrafast",
347
+ "supported": [
348
+ "x264",
349
+ "x265"
350
+ ]
351
+ },
352
+ {
353
+ "name": "hp",
354
+ "value": "hp",
355
+ "supported": [
356
+ "h264_nvenc",
357
+ "hevc_nvenc"
358
+ ]
359
+ },
360
+ {
361
+ "name": "hq",
362
+ "value": "hq",
363
+ "supported": [
364
+ "h264_nvenc",
365
+ "hevc_nvenc"
366
+ ]
367
+ },
368
+ {
369
+ "name": "bd",
370
+ "value": "bd",
371
+ "supported": [
372
+ "h264_nvenc",
373
+ "hevc_nvenc"
374
+ ]
375
+ },
376
+ {
377
+ "name": "lossless",
378
+ "value": "lossless",
379
+ "supported": [
380
+ "h264_nvenc",
381
+ "hevc_nvenc"
382
+ ]
383
+ },
384
+ {
385
+ "name": "losslesshp",
386
+ "value": "losslesshp",
387
+ "supported": [
388
+ "h264_nvenc",
389
+ "hevc_nvenc"
390
+ ]
391
+ },
392
+ {
393
+ "name": "None",
394
+ "value": "none"
395
+ }
396
+ ],
397
+ "passOptions": [
398
+ {
399
+ "name": "CRF",
400
+ "value": "crf"
401
+ },
402
+ {
403
+ "name": "1 Pass",
404
+ "value": "1"
405
+ },
406
+ {
407
+ "name": "2 Pass",
408
+ "value": "2"
409
+ }
410
+ ],
411
+ "pixelFormats": [
412
+ {
413
+ "name": "auto",
414
+ "value": "auto"
415
+ },
416
+ {
417
+ "name": "gray",
418
+ "value": "gray"
419
+ },
420
+ {
421
+ "name": "gray10le",
422
+ "value": "gray10le"
423
+ },
424
+ {
425
+ "name": "nv12",
426
+ "value": "nv12"
427
+ },
428
+ {
429
+ "name": "nv16",
430
+ "value": "nv16"
431
+ },
432
+ {
433
+ "name": "nv20le",
434
+ "value": "nv20le"
435
+ },
436
+ {
437
+ "name": "nv21",
438
+ "value": "nv21"
439
+ },
440
+ {
441
+ "name": "yuv420p",
442
+ "value": "yuv420p"
443
+ },
444
+ {
445
+ "name": "yuv420p10le",
446
+ "value": "yuv420p10le"
447
+ },
448
+ {
449
+ "name": "yuv422p",
450
+ "value": "yuv422p"
451
+ },
452
+ {
453
+ "name": "yuv422p10le",
454
+ "value": "yuv422p10le"
455
+ },
456
+ {
457
+ "name": "yuv444p",
458
+ "value": "yuv444p"
459
+ },
460
+ {
461
+ "name": "yuv444p10le",
462
+ "value": "yuv444p10le"
463
+ },
464
+ {
465
+ "name": "yuvj420p",
466
+ "value": "yuvj420p"
467
+ },
468
+ {
469
+ "name": "yuvj422p",
470
+ "value": "yuvj422p"
471
+ },
472
+ {
473
+ "name": "yuvj444p",
474
+ "value": "yuvj444p"
475
+ }
476
+ ],
477
+ "frameRates": [
478
+ {
479
+ "name": "auto",
480
+ "value": "auto"
481
+ },
482
+ {
483
+ "name": "ntsc",
484
+ "value": "ntsc"
485
+ },
486
+ {
487
+ "name": "pal",
488
+ "value": "pal"
489
+ },
490
+ {
491
+ "name": "film",
492
+ "value": "film"
493
+ },
494
+ {
495
+ "name": "23.976",
496
+ "value": "24000/1001"
497
+ },
498
+ {
499
+ "name": "24",
500
+ "value": "24"
501
+ },
502
+ {
503
+ "name": "25",
504
+ "value": "25"
505
+ },
506
+ {
507
+ "name": "29.97",
508
+ "value": "30000/1001"
509
+ },
510
+ {
511
+ "name": "30",
512
+ "value": "30"
513
+ },
514
+ {
515
+ "name": "48",
516
+ "value": "48"
517
+ },
518
+ {
519
+ "name": "50",
520
+ "value": "50"
521
+ },
522
+ {
523
+ "name": "59.94",
524
+ "value": "60000/1001"
525
+ },
526
+ {
527
+ "name": "60",
528
+ "value": "60"
529
+ }
530
+ ],
531
+ "speeds": [
532
+ {
533
+ "name": "auto",
534
+ "value": "auto"
535
+ },
536
+ {
537
+ "name": "10%",
538
+ "value": "10*PTS"
539
+ },
540
+ {
541
+ "name": "25%",
542
+ "value": "4*PTS"
543
+ },
544
+ {
545
+ "name": "50%",
546
+ "value": "2*PTS"
547
+ },
548
+ {
549
+ "name": "75%",
550
+ "value": "1.33333*PTS"
551
+ },
552
+ {
553
+ "name": "150%",
554
+ "value": ".66667*PTS"
555
+ },
556
+ {
557
+ "name": "200%",
558
+ "value": ".5*PTS"
559
+ },
560
+ {
561
+ "name": "250%",
562
+ "value": ".4*PTS"
563
+ },
564
+ {
565
+ "name": "300%",
566
+ "value": ".33333*PTS"
567
+ },
568
+ {
569
+ "name": "500%",
570
+ "value": ".2*PTS"
571
+ }
572
+ ],
573
+ "tunes": [
574
+ {
575
+ "name": "None",
576
+ "value": "none"
577
+ },
578
+ {
579
+ "name": "Film",
580
+ "value": "film"
581
+ },
582
+ {
583
+ "name": "Animation",
584
+ "value": "animation"
585
+ },
586
+ {
587
+ "name": "Grain",
588
+ "value": "grain"
589
+ },
590
+ {
591
+ "name": "Still Image",
592
+ "value": "stillimage"
593
+ },
594
+ {
595
+ "name": "Fast Decode",
596
+ "value": "fastdecode"
597
+ },
598
+ {
599
+ "name": "Zero Latency",
600
+ "value": "zerolatency"
601
+ }
602
+ ],
603
+ "profiles": [
604
+ {
605
+ "name": "None",
606
+ "value": "none"
607
+ },
608
+ {
609
+ "name": "Baseline",
610
+ "value": "baseline"
611
+ },
612
+ {
613
+ "name": "Main",
614
+ "value": "main"
615
+ },
616
+ {
617
+ "name": "High",
618
+ "value": "high"
619
+ }
620
+ ],
621
+ "levels": [
622
+ {
623
+ "name": "None",
624
+ "value": "none"
625
+ },
626
+ {
627
+ "name": "1.0",
628
+ "value": "1.0"
629
+ },
630
+ {
631
+ "name": "1.1",
632
+ "value": "1.1"
633
+ },
634
+ {
635
+ "name": "1.2",
636
+ "value": "1.2"
637
+ },
638
+ {
639
+ "name": "1.3",
640
+ "value": "1.3"
641
+ },
642
+ {
643
+ "name": "2.0",
644
+ "value": "2.0"
645
+ },
646
+ {
647
+ "name": "2.1",
648
+ "value": "2.1"
649
+ },
650
+ {
651
+ "name": "2.2",
652
+ "value": "2.2"
653
+ },
654
+ {
655
+ "name": "3.0",
656
+ "value": "3.0"
657
+ },
658
+ {
659
+ "name": "3.1",
660
+ "value": "3.1"
661
+ },
662
+ {
663
+ "name": "3.2",
664
+ "value": "3.2"
665
+ },
666
+ {
667
+ "name": "4.0",
668
+ "value": "4.0"
669
+ },
670
+ {
671
+ "name": "4.1",
672
+ "value": "4.1"
673
+ },
674
+ {
675
+ "name": "4.2",
676
+ "value": "4.2"
677
+ },
678
+ {
679
+ "name": "5.0",
680
+ "value": "5.0"
681
+ },
682
+ {
683
+ "name": "5.1",
684
+ "value": "5.1"
685
+ },
686
+ {
687
+ "name": "5.2",
688
+ "value": "5.2"
689
+ }
690
+ ],
691
+ "fastStart": [
692
+ {
693
+ "name": "Enabled (faststart)",
694
+ "value": true
695
+ },
696
+ {
697
+ "name": "None",
698
+ "value": false
699
+ }
700
+ ],
701
+ "sizes": [
702
+ {
703
+ "name": "Source",
704
+ "value": "source"
705
+ },
706
+ {
707
+ "name": "8K",
708
+ "value": "8192"
709
+ },
710
+ {
711
+ "name": "8K UHD",
712
+ "value": "7680"
713
+ },
714
+ {
715
+ "name": "4K",
716
+ "value": "4096"
717
+ },
718
+ {
719
+ "name": "4K UHD",
720
+ "value": "3840"
721
+ },
722
+ {
723
+ "name": "2K",
724
+ "value": "2048"
725
+ },
726
+ {
727
+ "name": "1600p",
728
+ "value": "2560"
729
+ },
730
+ {
731
+ "name": "1440p",
732
+ "value": "2560"
733
+ },
734
+ {
735
+ "name": "1200p",
736
+ "value": "1920"
737
+ },
738
+ {
739
+ "name": "1080p",
740
+ "value": "1920"
741
+ },
742
+ {
743
+ "name": "900p",
744
+ "value": "1600"
745
+ },
746
+ {
747
+ "name": "720p",
748
+ "value": "1280"
749
+ },
750
+ {
751
+ "name": "576p",
752
+ "value": "1024"
753
+ },
754
+ {
755
+ "name": "480p",
756
+ "value": "720"
757
+ },
758
+ {
759
+ "name": "320p",
760
+ "value": "480"
761
+ },
762
+ {
763
+ "name": "240p",
764
+ "value": "320"
765
+ },
766
+ {
767
+ "name": "Custom",
768
+ "value": "custom"
769
+ }
770
+ ],
771
+ "formats": [
772
+ {
773
+ "name": "Widescreen",
774
+ "value": "widescreen"
775
+ },
776
+ {
777
+ "name": "Full Screen",
778
+ "value": "fullscreen"
779
+ }
780
+ ],
781
+ "aspects": [
782
+ {
783
+ "name": "Auto",
784
+ "value": "auto"
785
+ },
786
+ {
787
+ "name": "1:1",
788
+ "value": "1:1"
789
+ },
790
+ {
791
+ "name": "2.4:1",
792
+ "value": "2.4:1"
793
+ },
794
+ {
795
+ "name": "3:2",
796
+ "value": "3:2"
797
+ },
798
+ {
799
+ "name": "4:3",
800
+ "value": "4:3"
801
+ },
802
+ {
803
+ "name": "5:4",
804
+ "value": "5:4"
805
+ },
806
+ {
807
+ "name": "8:7",
808
+ "value": "8:7"
809
+ },
810
+ {
811
+ "name": "14:10",
812
+ "value": "14:10"
813
+ },
814
+ {
815
+ "name": "16:9",
816
+ "value": "16:9"
817
+ },
818
+ {
819
+ "name": "16:10",
820
+ "value": "16:10"
821
+ },
822
+ {
823
+ "name": "19:10",
824
+ "value": "19:10"
825
+ },
826
+ {
827
+ "name": "21:9",
828
+ "value": "21:9"
829
+ },
830
+ {
831
+ "name": "32:9",
832
+ "value": "32:9"
833
+ }
834
+ ],
835
+ "scalings": [
836
+ {
837
+ "name": "Auto",
838
+ "value": "auto"
839
+ },
840
+ {
841
+ "name": "Neighbor",
842
+ "value": "neighbor"
843
+ },
844
+ {
845
+ "name": "Area",
846
+ "value": "area"
847
+ },
848
+ {
849
+ "name": "Fast Bilinear",
850
+ "value": "fast_bilinear"
851
+ },
852
+ {
853
+ "name": "Bilinear",
854
+ "value": "bilinear"
855
+ },
856
+ {
857
+ "name": "Bicubic",
858
+ "value": "bicubic"
859
+ },
860
+ {
861
+ "name": "Experimental",
862
+ "value": "experimental"
863
+ },
864
+ {
865
+ "name": "Bicublin",
866
+ "value": "bicublin"
867
+ },
868
+ {
869
+ "name": "Gauss",
870
+ "value": "gauss"
871
+ },
872
+ {
873
+ "name": "Sinc",
874
+ "value": "sinc"
875
+ },
876
+ {
877
+ "name": "Lanczos",
878
+ "value": "lanczos"
879
+ },
880
+ {
881
+ "name": "Spline",
882
+ "value": "spline"
883
+ }
884
+ ],
885
+ "audioStreams": [
886
+ {
887
+ "name": "None",
888
+ "value": "none"
889
+ },
890
+ {
891
+ "name": "All",
892
+ "value": "all"
893
+ },
894
+ {
895
+ "name": "1",
896
+ "value": "1"
897
+ },
898
+ {
899
+ "name": "2",
900
+ "value": "2"
901
+ },
902
+ {
903
+ "name": "3",
904
+ "value": "3"
905
+ },
906
+ {
907
+ "name": "4",
908
+ "value": "4"
909
+ },
910
+ {
911
+ "name": "5",
912
+ "value": "5"
913
+ },
914
+ {
915
+ "name": "6",
916
+ "value": "6"
917
+ },
918
+ {
919
+ "name": "7",
920
+ "value": "7"
921
+ },
922
+ {
923
+ "name": "8",
924
+ "value": "8"
925
+ }
926
+ ],
927
+ "audioChannels": [
928
+ {
929
+ "name": "Source",
930
+ "value": "source"
931
+ },
932
+ {
933
+ "name": "Mono",
934
+ "value": "1"
935
+ },
936
+ {
937
+ "name": "Stereo",
938
+ "value": "2"
939
+ },
940
+ {
941
+ "name": "5.1",
942
+ "value": "6"
943
+ }
944
+ ],
945
+ "audioQualities": [
946
+ {
947
+ "name": "Auto",
948
+ "value": "auto"
949
+ },
950
+ {
951
+ "name": "400",
952
+ "value": "400k"
953
+ },
954
+ {
955
+ "name": "320",
956
+ "value": "320k"
957
+ },
958
+ {
959
+ "name": "256",
960
+ "value": "256k"
961
+ },
962
+ {
963
+ "name": "224",
964
+ "value": "224k"
965
+ },
966
+ {
967
+ "name": "192",
968
+ "value": "192k"
969
+ },
970
+ {
971
+ "name": "160",
972
+ "value": "160k"
973
+ },
974
+ {
975
+ "name": "128",
976
+ "value": "128k"
977
+ },
978
+ {
979
+ "name": "96",
980
+ "value": "96k"
981
+ },
982
+ {
983
+ "name": "Custom",
984
+ "value": "custom"
985
+ },
986
+ {
987
+ "name": "Mute",
988
+ "value": "mute"
989
+ }
990
+ ],
991
+ "sampleRates": [
992
+ {
993
+ "name": "Auto",
994
+ "value": "auto"
995
+ },
996
+ {
997
+ "name": "7.35k",
998
+ "value": "7350"
999
+ },
1000
+ {
1001
+ "name": "8k",
1002
+ "value": "8000"
1003
+ },
1004
+ {
1005
+ "name": "11.025k",
1006
+ "value": "11025"
1007
+ },
1008
+ {
1009
+ "name": "12k",
1010
+ "value": "12000"
1011
+ },
1012
+ {
1013
+ "name": "16k",
1014
+ "value": "16000"
1015
+ },
1016
+ {
1017
+ "name": "22.05k",
1018
+ "value": "22050"
1019
+ },
1020
+ {
1021
+ "name": "24k",
1022
+ "value": "24000"
1023
+ },
1024
+ {
1025
+ "name": "32k",
1026
+ "value": "32000"
1027
+ },
1028
+ {
1029
+ "name": "44.1k",
1030
+ "value": "44100"
1031
+ },
1032
+ {
1033
+ "name": "48k",
1034
+ "value": "48000"
1035
+ }
1036
+ ],
1037
+ "deband": [
1038
+ {
1039
+ "name": "None",
1040
+ "value": false
1041
+ },
1042
+ {
1043
+ "name": "Enabled",
1044
+ "value": true
1045
+ }
1046
+ ],
1047
+ "deshake": [
1048
+ {
1049
+ "name": "None",
1050
+ "value": false
1051
+ },
1052
+ {
1053
+ "name": "Enabled",
1054
+ "value": true
1055
+ }
1056
+ ],
1057
+ "deflicker": [
1058
+ {
1059
+ "name": "None",
1060
+ "value": false
1061
+ },
1062
+ {
1063
+ "name": "Enabled",
1064
+ "value": true
1065
+ }
1066
+ ],
1067
+ "dejudder": [
1068
+ {
1069
+ "name": "None",
1070
+ "value": false
1071
+ },
1072
+ {
1073
+ "name": "Enabled",
1074
+ "value": true
1075
+ }
1076
+ ],
1077
+ "denoise": [
1078
+ {
1079
+ "name": "None",
1080
+ "value": "none"
1081
+ },
1082
+ {
1083
+ "name": "Default",
1084
+ "value": "default"
1085
+ },
1086
+ {
1087
+ "name": "Light",
1088
+ "value": "light"
1089
+ },
1090
+ {
1091
+ "name": "Medium",
1092
+ "value": "medium"
1093
+ },
1094
+ {
1095
+ "name": "Heavy",
1096
+ "value": "heavy"
1097
+ }
1098
+ ],
1099
+ "deinterlace": [
1100
+ {
1101
+ "name": "None",
1102
+ "value": "none"
1103
+ },
1104
+ {
1105
+ "name": "Frame",
1106
+ "value": "frame"
1107
+ },
1108
+ {
1109
+ "name": "Field",
1110
+ "value": "field"
1111
+ },
1112
+ {
1113
+ "name": "Frame Nospatial",
1114
+ "value": "frame_nospatial"
1115
+ },
1116
+ {
1117
+ "name": "Field Nospatial",
1118
+ "value": "field_nospatial"
1119
+ }
1120
+ ],
1121
+ "extraOptions": [
1122
+ {
1123
+ "text": "Force output file format.",
1124
+ "value": "f"
1125
+ },
1126
+ {
1127
+ "text": "Overwrite output files without asking.",
1128
+ "value": "y"
1129
+ },
1130
+ {
1131
+ "text": "Do not overwrite output files, and exit immediately if a specified output file already exists.",
1132
+ "value": "n"
1133
+ },
1134
+ {
1135
+ "text": "Send program-friendly progress information to stdout.",
1136
+ "value": "progress"
1137
+ },
1138
+ {
1139
+ "text": "Suppress printing banner.",
1140
+ "value": "hide_banner"
1141
+ },
1142
+ {
1143
+ "text": "Dump full command line and log output to a file named program-YYYYMMDD-HHMMSS.log in the current directory.",
1144
+ "value": "report"
1145
+ }
1146
+ ],
1147
+ "logLevels": [
1148
+ {
1149
+ "name": "None",
1150
+ "value": "none"
1151
+ },
1152
+ {
1153
+ "name": "Quiet",
1154
+ "value": "quiet"
1155
+ },
1156
+ {
1157
+ "name": "Panic",
1158
+ "value": "panic"
1159
+ },
1160
+ {
1161
+ "name": "Fatal",
1162
+ "value": "fatal"
1163
+ },
1164
+ {
1165
+ "name": "Error",
1166
+ "value": "error"
1167
+ },
1168
+ {
1169
+ "name": "Warning",
1170
+ "value": "warning"
1171
+ },
1172
+ {
1173
+ "name": "Info",
1174
+ "value": "info"
1175
+ },
1176
+ {
1177
+ "name": "Verbose",
1178
+ "value": "verbose"
1179
+ },
1180
+ {
1181
+ "name": "Debug",
1182
+ "value": "debug"
1183
+ },
1184
+ {
1185
+ "name": "Trace",
1186
+ "value": "trace"
1187
+ }
1188
+ ]
1189
+ }
functions.py ADDED
@@ -0,0 +1,515 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ util functions and classes
3
+ """
4
+ import json
5
+ from pprint import pprint
6
+ from tempfile import _TemporaryFileWrapper
7
+ from typing import List
8
+
9
+ import gradio as gr
10
+ from gradio.components import Component
11
+
12
+ def parse(param: json) -> dict:
13
+ with open(param) as file:
14
+ return json.load(file)
15
+
16
+
17
+ data = parse("./data.json")
18
+ codecs = parse("./codecs.json")
19
+
20
+ """Video"""
21
+ containers = [j.get("name") for i in data["containers"]
22
+ for j in data["containers"][i]]
23
+ video_containers = [i.get("name") for i in data["containers"]["video"]]
24
+ video_codecs = [i.get("value") for i in data["codecs"]["video"]]
25
+ video_aspect_ratio = [i.get("name") for i in data["aspects"]]
26
+ video_scaling = [i.get("name") for i in data["scalings"]]
27
+ """ Audio """
28
+ audio_containers = [i.get("name") for i in data["containers"]["audio"]]
29
+ audio_codecs = [i.get("value") for i in data["codecs"]["audio"]]
30
+ audio_channels = [i.get("name") for i in data["audioChannels"]]
31
+ audio_quality = [i.get("name") for i in data["audioQualities"]]
32
+ audio_sample_rates = [i.get("name") for i in data["sampleRates"]]
33
+
34
+ """ Video & Audio Filters """
35
+ # deband=[i.get("name") for i in data["deband"]]
36
+ # deflicker=[i.get("name") for i in data["deflicker"]]
37
+ # deshake=[i.get("name") for i in data["deshake"]]
38
+ # dejudder=[i.get("name") for i in data["dejudder"]]
39
+ # denoise=[i.get("name") for i in data["denoise"]]
40
+ # deinterlace=[i.get("name") for i in data["deinterlace"]]
41
+ filters = ["deband", "deflicker", "deshake",
42
+ "dejudder", "denoise", "deinterlace"]
43
+ vf = [{vFilter: names} for vFilter in filters for names in [
44
+ [i for i in data[vFilter]]]]
45
+
46
+ presets = [i.get("name") for i in data["presets"]]
47
+ profiles = [i.get("name") for i in data["profiles"]]
48
+ speeds = [i.get("name") for i in data["speeds"]]
49
+
50
+
51
+ outputMap = parse("./mappings.json")
52
+ newoutputMap = parse("./new_mappings.json")
53
+ """Output Mappings of commands to value
54
+ audioQuality -b:a 128k
55
+ """
56
+
57
+
58
+ class CommandBuilder():
59
+ """Takes a collection of gradio layout elements and attaches
60
+ a function to each component in the context
61
+ to build an array of ffmpeg commands"""
62
+
63
+ def __call__(self, *args, **kwds):
64
+ return [i.value for i in self._component]
65
+
66
+ def do(self, *inputs, **kwds):
67
+ for comp in self._component:
68
+ if comp.label is not None:
69
+ self.changefunc(comp, "", comp.value)
70
+
71
+ def reset(self):
72
+ self.outputDict = {"vf": {}, "af": {}}
73
+ self.commands=""
74
+ self.vf, self.af, self.extra = ([] for _ in range(3))
75
+
76
+ def __init__(self, *inputs: gr.Blocks) -> None:
77
+ """
78
+ Parameters:
79
+ *inputs: A tuple of layout blocks containing components(Textbox,Button...).
80
+ """
81
+
82
+ self.outputDict = {"vf": {}, "af": {}}
83
+ self.formatOutputDict = {"vf": {}, "af": {}}
84
+ # state=gr.Variable()
85
+ # state2=gr.Variable()
86
+
87
+ self._component: List[Component] = []
88
+ self.vf, self.af, self.extra = ([] for _ in range(3))
89
+ self.commands = ""
90
+ if inputs is None:
91
+ return None
92
+ for i in inputs:
93
+ self._component += self._get_component_instance(i)
94
+ for comp in self._component:
95
+ state = gr.Variable()
96
+ state2 = gr.Variable()
97
+ if comp.label is not None:
98
+ state.value = comp
99
+ state2.value = comp.label
100
+ comp.change(fn=self.changefunc, inputs=[
101
+ state, state2, comp], outputs=[])
102
+
103
+ def changefunc(self, input: gr.components.IOComponent, c_label="", newValue=""):
104
+ label, *_ = input.label.strip(": \n").lower().split(
105
+ ) if type(input.label) != list else "".join(input.label).strip(": ").lower().split()
106
+ label += "".join(_).title()
107
+ key = newoutputMap.get(label)
108
+ lst_extra, vf, af = ([] for _ in range(3))
109
+ if newValue not in [None, "Source", "Auto", "", "None", "none", 0]:
110
+ self.setVf(label, newValue)
111
+ self.setAf(label, newValue)
112
+ self.setF(label, newValue)
113
+ for val in self.outputDict:
114
+ if val == "vf":
115
+ vf = self.outputDict.get(val).values()
116
+ vf = ",".join(list(vf))
117
+ elif val == "af":
118
+ af = self.outputDict.get(val).values()
119
+ af = ",".join(list(af))
120
+ pass
121
+ else:
122
+ lst_extra.extend([val, self.outputDict.get(val)])
123
+
124
+ else:
125
+ self.outputDict.pop(key, "No Key Exists")
126
+ self.outputDict["vf"].pop(label, "No Key Exists")
127
+ self.outputDict["af"].pop(label, "No Key Exists")
128
+ self.vf = f"-vf '{vf}'" if vf else ""
129
+ self.af = f"-af '{af}'" if af else ""
130
+ self.extra = " ".join(lst_extra)
131
+ self.commands = f"{self.vf} {self.af} {self.extra}"
132
+
133
+ print(self.vf, self.af, self.extra)
134
+
135
+ def setVf(self, label:str, newValue:"str| int"):
136
+ """Sets Video filters
137
+
138
+ Args:
139
+ label : label of components
140
+ newValue : value of component
141
+ """
142
+ if newoutputMap["vf"].get(label):
143
+ key = newoutputMap["vf"].get(label)
144
+ if label in ["deinterlace", "denoise"]:
145
+ value = "_".join(newValue.lower().split())
146
+ arg = key.get(value, None)
147
+ self.outputDict["vf"].update({label: arg})
148
+ else:
149
+ self.outputDict["vf"].update({key: key})
150
+
151
+ def setF(self, label, newValue):
152
+ """ Sets Extra filters
153
+ Args:
154
+ label : label of components
155
+ newValue : value of component
156
+ """
157
+ if newoutputMap.get(label):
158
+ key = newoutputMap.get(label)
159
+ if label in ["video", "audio"]:
160
+ value=codecs.get(label).get(newValue,newValue)
161
+ print(value)
162
+ self.outputDict.update({key:value})
163
+ elif label in ["startTime", "stopTime"]:
164
+ self.outputDict.update({key: newValue})
165
+ else:
166
+ value = "".join([i.get("value", "None") for i in data.get(
167
+ label) if i.get("name", None) == newValue])
168
+ self.outputDict.update({key: value})
169
+
170
+ def setAf(self, label:str, newValue:"str|int"):
171
+ """ Sets Extra filters
172
+ Args:
173
+ label : label of components
174
+ newValue : value of component
175
+ """
176
+ if newoutputMap["af"].get(label):
177
+ value = int(newValue)/100
178
+ arg = f"{label}={value}"
179
+ self.outputDict["af"].update({label: arg})
180
+
181
+ def update(self, Component: Component):
182
+ for comp in self._component:
183
+ comp.change(lambda: gr.update(
184
+ value=self.outputDict), [], [Component])
185
+
186
+ def _get_component_instance(self, inputs: gr.Blocks) -> List[Component]:
187
+ """
188
+ returns components present in a layout block
189
+ Parameters:
190
+ inputs: layout block
191
+ """
192
+ res=[]
193
+ for i in inputs.children:
194
+ # print(i,hasattr(i,"children"))
195
+ if not (hasattr(i,"children")):
196
+ # res.append(gr.components.get_component_instance(i,render=True))
197
+ res+=[gr.components.get_component_instance(i,render=True)]
198
+ # print(res)
199
+ elif hasattr(i,"children"):
200
+ res+=self._get_component_instance(i)
201
+ # print(res)
202
+ return res
203
+ # return [gr.components.get_component_instance(i, render=True) for i in inputs.children if not hasattr(i, "children")]
204
+
205
+ def setVideoFilters(self, options):
206
+ value = self.outputDict.get(options, "-")
207
+ filters = newoutputMap.get(options, None)
208
+ arg = ""
209
+ if options in ["deinterlace", "denoise"]:
210
+ value = "_".join(value.lower().split())
211
+ arg = filters.get(value, None)
212
+ # self.vf.append(arg)
213
+ self.outputDict["vf"].update({options: arg})
214
+ return True
215
+ if options in ["deband", "deflicker", "deshake", "dejudder"]:
216
+ arg = filters
217
+ self.outputDict["vf"].update({options: arg})
218
+ return True
219
+
220
+ return
221
+
222
+ def setAudioFilters(self, options):
223
+ value = self.outputDict.get(options, "-")
224
+ if options in ["acontrast"]:
225
+ value = int(value)/100
226
+ arg = f"{options}={value}"
227
+
228
+ self.outputDict["af"].update({options: arg})
229
+ return True
230
+ return
231
+
232
+ def setFormat(self, options):
233
+ value = self.outputDict.get(options, "-")
234
+ filters = newoutputMap.get(options, None)
235
+ if options in ["video", "audio"]:
236
+ value = "".join([i.get("value", "None") for i in data.get(
237
+ "codecs").get(options) if i.get("name", None) == value])
238
+ arg = f"{filters} {value}"
239
+ self.outputDict.update({options: arg})
240
+ return True
241
+ elif data.get(options) == None:
242
+ arg = f"{filters} {value}"
243
+ self.outputDict.update({options: arg})
244
+ return True
245
+ elif options != "clip":
246
+ value = "".join([i.get("value", "None") for i in data.get(
247
+ options) if i.get("name", None) == value])
248
+ arg = f"{filters} {value}"
249
+ self.outputDict.update({options: arg})
250
+
251
+ def build(self):
252
+ for i in self.outputDict:
253
+ if self.setVideoFilters(i):
254
+ continue
255
+ elif self.setAudioFilters(i):
256
+ continue
257
+ else:
258
+ self.setFormat(i)
259
+ lst_extra, vf, af = ([] for _ in range(3))
260
+ for val in self.outputDict:
261
+ if val == "vf":
262
+ vf = self.outputDict.get(val).values()
263
+ vf = ",".join(list(vf))
264
+ elif val == "af":
265
+ af = self.outputDict.get(val).values()
266
+ af = ",".join(list(af))
267
+ else:
268
+ lst_extra.append(self.outputDict.get(val))
269
+ # print(lst_extra, "temp x")
270
+ # if vf:self.vf=f"-vf '{vf}'"
271
+ # if af:self.af=f"-af '{af}'"
272
+ self.vf = f"-vf '{vf}'" if vf else ""
273
+ self.af = f"-af '{af}'" if af else ""
274
+ self.extra = " ".join(lst_extra)
275
+ self.commands = f"{self.vf} {self.af} {self.extra}"
276
+
277
+ def startfunc(self, input: gr.components.IOComponent, c_label="", newValue=""):
278
+ label, *_ = input.label.strip(": ").lower().split(
279
+ ) if type(input.label) != list else "".join(input.label).strip(": ").lower().split()
280
+ label += "".join(_).title()
281
+ if newValue not in [None, "Source", "Auto", "", "None", 0]:
282
+ self.outputDict["vf"].update({label: newValue})
283
+ self.outputDict["af"].update({label: newValue})
284
+ self.outputDict.update({label: newValue})
285
+ else:
286
+ self.outputDict.pop(label, "No Key Exists")
287
+ self.outputDict["vf"].pop(label, "No Key Exists")
288
+ self.outputDict["af"].pop(label, "No Key Exists")
289
+ # self.formatOutputDict["vf"].pop(label, "Key is None or similar")
290
+ # self.formatOutputDict["af"].pop(label, "Key is None or similar")
291
+ # self.formatOutputDict.pop(label, "Key is None or similar")
292
+ print(self.outputDict)
293
+ self.build()
294
+
295
+
296
+ # def somefunc(input: gr.components.IOComponent, c_label=""):
297
+ # label = ""
298
+ # output = {}
299
+ # print(input, c_label)
300
+ # label, *_ = input.label.strip(": ").lower().split(
301
+ # ) if type(input.label) != list else "".join(input.label).strip(": ").lower().split()
302
+ # label += "".join(_).title()
303
+ # print(newoutputMap.get(label), label, c_label)
304
+ # if c_label not in [None, "Source", "Auto", ""]:
305
+ # print(input.value)
306
+ # output.update({label: c_label})
307
+ # else:
308
+ # output.pop(label, "No Key Exists")
309
+ # pprint(output)
310
+
311
+ # def mediaChange(option):
312
+ # no_=gr.update(visible=False)
313
+ # if option in video_containers:
314
+ # output=gr.update(visible=True)
315
+ # return [no_,output]
316
+ # elif option in audio_containers:
317
+ # output=gr.update(visible=True)
318
+ # return [output,no_]
319
+ # else:
320
+ # output=gr.update(visible=False)
321
+ # return [no_,no_]
322
+
323
+
324
+ def mediaChange(option:str,state)-> List[Component]:
325
+ """
326
+ Allows playing the media in various options,
327
+ Video, Audio or File
328
+
329
+ Args:
330
+ option : Clicked buttons value
331
+
332
+ Returns:
333
+ List[Component]: list of toggled output components to display
334
+ """
335
+ ops = {"Audio": gr.update(visible=True,value=state)}
336
+ ops2 = {"Video": gr.update(visible=True,value=state)}
337
+ ops3 = {"File": gr.update(visible=True,value=state, interactive=False)}
338
+
339
+ def chosen(x): return x.get(option, gr.update(visible=False))
340
+ return [chosen(ops), chosen(ops2), chosen(ops3)]
341
+
342
+
343
+ # def videoChange(value):
344
+ # print(value.name)
345
+
346
+ # if option in video_containers:
347
+ # output=gr.update(visible=True)
348
+ # return [no_,output]
349
+ # elif option in audio_containers:
350
+ # output=gr.update(visible=True)
351
+ # return [output,no_]
352
+ # else:
353
+ # output=gr.update(visible=False)
354
+ # return [no_,no_]
355
+
356
+
357
+
358
+
359
+ """Helper Functions for Processing """
360
+
361
+
362
+ # def clear(*input):
363
+ # print(input, " clear_func")
364
+ # # for i in [inp for i in input for inp in i]:
365
+ # # print(i, hasattr(i,"cleared_value"),type(i))
366
+ # # a=default_clear(input_components)
367
+ # def clear_func(x): return [component.cleared_value if hasattr(
368
+ # component, "cleared_value") else None for component in x]
369
+ # print(clear_func(input))
370
+ # return clear_func(input)
371
+
372
+ def customBitrate(choice:int)-> Component:
373
+ """
374
+ Toggle a component for custom Audio Quality
375
+ visible/none
376
+ Args:
377
+ choice : Custom audio quality
378
+
379
+ Returns:
380
+ Component: component toggle state
381
+ """
382
+ if choice == "Custom":
383
+ return gr.update(visible=True)
384
+ else:
385
+ return gr.update(visible=False, value=0)
386
+
387
+
388
+ def supported_codecs(format: str)-> List[Component]:
389
+ """
390
+ Changes video and audio components with appropriate
391
+ options according to passed format
392
+
393
+ Args:
394
+ format: passed media codec (x264,x265)
395
+
396
+ Returns:
397
+ List[Component]: list of components with updated choices
398
+ """
399
+ if format:
400
+ format = format.lower()
401
+ video_lst = [val.get("value") for val in data["codecs"]["video"]
402
+ if val.get("supported") == None or format in val["supported"]]
403
+ audio_lst = [val.get("value") for val in data["codecs"]["audio"]
404
+ if val.get("supported") == None or format in val["supported"]]
405
+ return [gr.update(choices=video_lst), gr.update(choices=audio_lst)]
406
+
407
+
408
+ def supported_presets(format: str)-> Component:
409
+ """
410
+ Changes presets component with appropriate
411
+ options according to passed format
412
+ Args:
413
+ format: passed media codec (x264,x265)
414
+
415
+ Returns:
416
+ Component: component with updated choice list (video codecs)
417
+ """
418
+ if format:
419
+ format = format.lower()
420
+ video_lst = [val.get("name") for val in data["presets"]
421
+ if val.get("supported") == None or format in val["supported"]]
422
+ return gr.update(choices=video_lst)
423
+
424
+
425
+ def change_clipbox(choice:str)-> List[Component]:
426
+ """
427
+ Toggles the clipping Textbox
428
+
429
+ Args:
430
+ choice: Enabled/None
431
+
432
+ Returns:
433
+ List[Component]: list of components with visible state of the clip components
434
+ """
435
+ if choice == "Enabled":
436
+ return [gr.update(visible=True, value="00:00"), gr.update(visible=True, value="00:10")]
437
+ else:
438
+ return [gr.update(visible=False, value=""), gr.update(visible=False, value="")]
439
+
440
+
441
+ def updateOutput(file: _TemporaryFileWrapper)-> Component:
442
+ if file:
443
+ print(file.name)
444
+ return gr.update(value=file.name)
445
+
446
+
447
+ def get_component_instance(inputs: gr.Blocks)-> List[Component]:
448
+ """ returns only components
449
+
450
+ Args:
451
+ inputs: layout elements
452
+
453
+ Returns:
454
+ List[Component]: components
455
+ """
456
+ return [gr.components.get_component_instance(i, render=True) for i in inputs.children]
457
+
458
+
459
+ class Clear(CommandBuilder):
460
+ """ Class for clearing components in layouts
461
+ """
462
+
463
+ def __call__(self, *args, **kwds):
464
+ return self._component
465
+
466
+ def __str__(self):
467
+ return f"{self._component} __clear__ class"
468
+
469
+ def __repr__(self):
470
+ return self._component
471
+
472
+ def __init__(self, *input_component: gr.Blocks()) -> None:
473
+ """
474
+ Parameters:
475
+ *input_component: A tuple of layout blocks containing components
476
+ """
477
+ self._component = []
478
+ if input_component is not None:
479
+ for i in input_component:
480
+ # self._component += super()._get_component_instance(i)
481
+ self._component += self.__get_component_instance(i)
482
+
483
+ def __get_component_instance(self, inputs: gr.Blocks) -> list:
484
+ # print(inputs, " class instance")
485
+ res=[]
486
+ # print(*inputs.children)
487
+ for i in inputs.children:
488
+ # print(i,hasattr(i,"children"))
489
+ if not (hasattr(i,"children")):
490
+ # res.append(gr.components.get_component_instance(i,render=True))
491
+ res+=[gr.components.get_component_instance(i,render=True)]
492
+ # print(i)
493
+ elif hasattr(i,"children"):
494
+ # print(*i.children)
495
+ res+=self.__get_component_instance(i)
496
+ # res=[gr.components.get_component_instance(i, render=True) for i in inputs.children if not hasattr(i, "children")]
497
+ # print(res,"__ result")
498
+ # print(res)
499
+ return res
500
+ # return [gr.components.get_component_instance(i, render=True) for i in inputs.children if not hasattr(i, "children")]
501
+
502
+ def add(self, *args):
503
+ print(args, type(args))
504
+ if args is not None:
505
+ for i in args:
506
+ self._component += super().__get_component_instance(i)
507
+ return self._component
508
+
509
+ def clear(self, *args):
510
+ """
511
+ Function to clear components from a Block in the class instance
512
+ """
513
+ def clear_func(x): return [component.cleared_value if hasattr(
514
+ component, "cleared_value") else component.value for component in x]
515
+ return clear_func(self._component)
images/gradio-app.png ADDED
mappings.json ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "protocols": "",
3
+ "startTime": "-ss",
4
+ "stopTime": "-to",
5
+
6
+ "video": "-c:v",
7
+ "audio": "-c:a",
8
+ "bitrate": "-b:v",
9
+ "minrate": "-minrate",
10
+ "maxrate": "-maxrate",
11
+ "bufsize": "-bufsize",
12
+ "gopsize": "-g",
13
+ "pixelFormat": "-pix_fmt",
14
+
15
+ "containers": {
16
+ "video": "-c:v",
17
+ "audio": "-c:a"
18
+ },
19
+ "clipping": {
20
+ "startTime": "-ss",
21
+ "stopTime": "-to"
22
+ },
23
+ "codecs": "",
24
+ "presets": "-preset",
25
+ "passOptions": "-pass",
26
+ "pixelformats": "",
27
+ "frameRates": "-r",
28
+ "speeds": "",
29
+ "tunes": "-tune",
30
+ "profiles": "-profile:v",
31
+ "levels": "",
32
+ "fastStart": "-movflags",
33
+ "sizes": "",
34
+ "formats": "",
35
+ "aspects": "-aspect",
36
+ "scalings": "",
37
+
38
+
39
+ "audioStreams": "",
40
+ "audioChannels": "-ac",
41
+ "audioQualities": "-b:a",
42
+ "sampleRates": "-ar",
43
+
44
+ "deband": "deband",
45
+ "deshake": "deshake",
46
+ "deflicker": "deflicker",
47
+ "dejudder": "dejudder",
48
+ "denoise": {
49
+ "light": "removegrain=22",
50
+ "medium": "vaguedenoiser=threshold=3:method=soft:nsteps=5",
51
+ "heavy": "vaguedenoiser=threshold=6:method=soft:nsteps=5",
52
+ "default": "removegrain=0"
53
+ },
54
+ "deinterlace": {
55
+ "frame": "yadif=0:-1:0",
56
+ "field": "yadif=1:-1:0",
57
+ "frame_nospatial": "yadif=2:-1:0",
58
+ "field_nospatial": "yadif=3:-1:0"
59
+ },
60
+ "extraOptions": "",
61
+ "logLevels": ""
62
+ }
new_mappings.json ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "vf": {
3
+ "deband": "deband",
4
+ "deshake": "deshake",
5
+ "deflicker": "deflicker",
6
+ "dejudder": "dejudder",
7
+ "denoise": {
8
+ "light": "removegrain=22",
9
+ "medium": "vaguedenoiser=threshold=3:method=soft:nsteps=5",
10
+ "heavy": "vaguedenoiser=threshold=6:method=soft:nsteps=5",
11
+ "default": "removegrain=0"
12
+ },
13
+ "deinterlace": {
14
+ "frame": "yadif=0:-1:0",
15
+ "field": "yadif=1:-1:0",
16
+ "frame_nospatial": "yadif=2:-1:0",
17
+ "field_nospatial": "yadif=3:-1:0"
18
+ }
19
+ },
20
+ "af": {
21
+ "acontrast": "0"
22
+ },
23
+ "protocols": "",
24
+ "startTime": "-ss",
25
+ "stopTime": "-to",
26
+
27
+ "video": "-c:v",
28
+ "audio": "-c:a",
29
+ "bitrate": "-b:v",
30
+ "minrate": "-minrate",
31
+ "maxrate": "-maxrate",
32
+ "bufsize": "-bufsize",
33
+ "gopsize": "-g",
34
+ "pixelFormat": "-pix_fmt",
35
+
36
+ "containers": {
37
+ "video": "-c:v",
38
+ "audio": "-c:a"
39
+ },
40
+ "clipping": {
41
+ "startTime": "-ss",
42
+ "stopTime": "-to"
43
+ },
44
+ "codecs": "",
45
+ "presets": "-preset",
46
+ "passOptions": "-pass",
47
+ "pixelformats": "",
48
+ "frameRates": "-r",
49
+ "speeds": "",
50
+ "tunes": "-tune",
51
+ "profiles": "-profile:v",
52
+ "levels": "",
53
+ "fastStart": "-movflags",
54
+ "sizes": "",
55
+ "formats": "",
56
+ "aspects": "-aspect",
57
+ "scalings": "",
58
+
59
+
60
+ "audioStreams": "",
61
+ "audioChannels": "-ac",
62
+ "audioQualities": "-b:a",
63
+ "sampleRates": "-ar",
64
+
65
+
66
+ "extraOptions": "",
67
+ "logLevels": ""
68
+ }
output.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format": {
3
+ "container": "mp4",
4
+ "clip": false
5
+ },
6
+ "video": {
7
+ "codec": "libx264",
8
+ "preset": "none",
9
+ "pass": "1",
10
+ "crf": 23,
11
+ "pixel_format": "auto",
12
+ "frame_rate": "auto",
13
+ "speed": "auto",
14
+ "tune": "none",
15
+ "profile": "none",
16
+ "level": "none",
17
+ "faststart": false,
18
+ "size": "source",
19
+ "width": "1080",
20
+ "height": "1920",
21
+ "format": "widescreen",
22
+ "aspect": "auto",
23
+ "scaling": "auto",
24
+ "codec_options": ""
25
+ },
26
+ "audio": {
27
+ "codec": "copy",
28
+ "channel": "source",
29
+ "quality": "auto",
30
+ "sampleRate": "auto",
31
+ "volume": "100"
32
+ },
33
+ "filter": {
34
+ "deband": false,
35
+ "deshake": false,
36
+ "deflicker": false,
37
+ "dejudder": false,
38
+ "denoise": "none",
39
+ "deinterlace": "none",
40
+ "brightness": "0",
41
+ "contrast": "1",
42
+ "saturation": "0",
43
+ "gamma": "0",
44
+ "acontrast": "33"
45
+ }
46
+ }
requirements.txt ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiohttp==3.8.1
2
+ aiosignal==1.2.0
3
+ analytics-python==1.4.0
4
+ anyio==3.6.1
5
+ async-timeout==4.0.2
6
+ attrs==22.1.0
7
+ backoff==1.10.0
8
+ bcrypt==4.0.0
9
+ certifi==2022.6.15
10
+ cffi==1.15.1
11
+ charset-normalizer==2.1.1
12
+ click==8.1.3
13
+ cryptography==37.0.4
14
+ cycler==0.11.0
15
+ fastapi==0.81.0
16
+ ffmpy==0.3.0
17
+ fonttools==4.37.1
18
+ frozenlist==1.3.1
19
+ fsspec==2022.7.1
20
+ gradio==3.3.1
21
+ h11==0.12.0
22
+ httpcore==0.15.0
23
+ httpx==0.23.0
24
+ idna==3.3
25
+ Jinja2==3.1.2
26
+ kiwisolver==1.4.4
27
+ linkify-it-py==1.0.3
28
+ markdown-it-py==2.1.0
29
+ MarkupSafe==2.1.1
30
+ matplotlib==3.5.3
31
+ mdit-py-plugins==0.3.0
32
+ mdurl==0.1.2
33
+ monotonic==1.6
34
+ multidict==6.0.2
35
+ numpy==1.23.2
36
+ orjson==3.8.0
37
+ packaging==21.3
38
+ pandas==1.4.3
39
+ paramiko==2.11.0
40
+ Pillow==9.2.0
41
+ pycparser==2.21
42
+ pycryptodome==3.15.0
43
+ pydantic==1.9.2
44
+ pydub==0.25.1
45
+ PyNaCl==1.5.0
46
+ pyparsing==3.0.9
47
+ python-dateutil==2.8.2
48
+ python-multipart==0.0.5
49
+ pytz==2022.2.1
50
+ PyYAML==6.0
51
+ requests==2.28.1
52
+ rfc3986==1.5.0
53
+ six==1.16.0
54
+ sniffio==1.2.0
55
+ starlette==0.19.1
56
+ typing-extensions==4.3.0
57
+ uc-micro-py==1.0.1
58
+ urllib3==1.26.12
59
+ uvicorn==0.18.3
60
+ websockets==10.3
61
+ yarl==1.8.1
styles.css ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ #outputtext {
2
+ color: green;
3
+ }
4
+ #acontrast {
5
+ width: 50%;
6
+ }
7
+ #button{
8
+ width: 30%
9
+ }