eienmojiki commited on
Commit
4def516
1 Parent(s): 9fc0ec4

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -0
app.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from moviepy.editor import *
2
+
3
+ from PIL import Image, GifImagePlugin
4
+
5
+ import tempfile
6
+ import gradio as gr
7
+
8
+ def get_video_detail(video_path):
9
+ info = VideoFileClip(video_path)
10
+ return 0, info.duration, info.fps, max(info.size)
11
+
12
+ def convert_video_to_gif(
13
+ input: str,
14
+ start: float = 0,
15
+ end: float | None = None,
16
+ fps: int | None = None,
17
+ quality: int | None = None
18
+ ) -> Image.Image:
19
+ """
20
+ Convert video to GIF image
21
+
22
+ Args:
23
+ input (str): Path to video file.
24
+ start (float, optional): Start time in seconds. Defaults to 0.
25
+ end (float, optional): End time in seconds. Defaults to None.
26
+ fps (int, optional): Frames per second. Defaults to None (max fps).
27
+ quality (int, optional): Image quality. Defaults to None (max quality).
28
+
29
+ Returns:
30
+ Image.Image: GIF image
31
+
32
+ Examples:
33
+ >>> convert_video_to_gif("input.mp4")
34
+
35
+ """
36
+ # Get video input & info
37
+ clip = VideoFileClip(input)
38
+
39
+ max_fps = clip.fps
40
+ max_duration = clip.duration
41
+ max_res = max(clip.size)
42
+
43
+ if end is None:
44
+ end = max_duration
45
+
46
+ if end > max_duration:
47
+ raise ValueError(f'End time {end} is longer than video duration {max_duration}')
48
+
49
+ if fps > max_fps:
50
+ raise ValueError(f'FPS {fps} is greater than video FPS {max_fps}')
51
+
52
+ if quality is None:
53
+ quality = max_res
54
+
55
+ if quality > max_res:
56
+ raise ValueError(f'Quality must be less than video max resolution {max_res}, but is {quality}')
57
+
58
+
59
+ clip = clip.subclip(start, end)
60
+ target_height = quality
61
+ aspect_ratio = clip.size[0] / clip.size[1]
62
+ target_width = int(target_height * aspect_ratio)
63
+ clip = clip.resize((target_width, target_height))
64
+
65
+ clip = clip.set_fps(fps)
66
+
67
+ # Create a temporary file
68
+ with tempfile.NamedTemporaryFile(suffix='.gif') as temp_file:
69
+ # Write the GIF to the temporary file
70
+ clip.write_gif(temp_file.name)
71
+
72
+ # Read the GIF from the temporary file
73
+ gif_image = Image.open(temp_file.name)
74
+
75
+ return gif_image
76
+
77
+
78
+ with gr.Blocks(
79
+ theme = gr.themes.Base(
80
+ font = [gr.themes.GoogleFont("Outfit"), "Arial", "sans-serif"],
81
+ ),
82
+ delete_cache=(86400, 86400)
83
+ ) as demo:
84
+ input = gr.Video(interactive=True)
85
+ save = gr.Text(label="Cache path", interactive=False)
86
+ with gr.Row():
87
+ start = gr.Number(
88
+ label="Start",
89
+ info="Video start time in seconds",
90
+ interactive=True
91
+ )
92
+ end = gr.Number(
93
+ label="End",
94
+ info="Video end time in seconds",
95
+ interactive=True
96
+ )
97
+
98
+ with gr.Row():
99
+ fps = gr.Number(
100
+ label="FPS",
101
+ info="Frame per second",
102
+ interactive=True
103
+ )
104
+ quality = gr.Number(
105
+ label="Quality",
106
+ info="Nax resolution available",
107
+ interactive=True
108
+ )
109
+
110
+ run_btn = gr.Button("Convert")
111
+ output = gr.Gallery(
112
+ label="GIF",
113
+ format="gif"
114
+ )
115
+
116
+ input.change(
117
+ fn=lambda x: x,
118
+ inputs=input,
119
+ outputs=save,
120
+ queue=False,
121
+ api_name=False
122
+ ).then(
123
+ fn=get_video_detail,
124
+ inputs=save,
125
+ outputs=[start, end, fps, quality],
126
+ queue=False,
127
+ api_name=False
128
+ )
129
+
130
+ run_btn.click(
131
+ fn=convert_video_to_gif,
132
+ inputs=[save, start, end, fps, quality],
133
+ outputs=output,
134
+ api_name="convert"
135
+ )
136
+
137
+ if __name__ == "__main__":
138
+ demo.queue(max_size=20).launch(show_error=True)