-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathstreamlit_app.py
135 lines (104 loc) · 4.52 KB
/
streamlit_app.py
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
import streamlit as st
import os
import base64
import tempfile
from PIL import Image
import numpy as np
from moviepy.editor import VideoFileClip
import moviepy.video.fx.all as vfx
## Session state ##
if 'clip_width' not in st.session_state:
st.session_state.clip_width = 0
if 'clip_height' not in st.session_state:
st.session_state.clip_height = 0
if 'clip_duration' not in st.session_state:
st.session_state.clip_duration = 0
if 'clip_fps' not in st.session_state:
st.session_state.clip_fps = 0
if 'clip_total_frames' not in st.session_state:
st.session_state.clip_total_frames = 0
# App title
st.title('🤹 Make A GIF 🏄♂️')
## Upload file ##
st.sidebar.header('Upload file')
uploaded_file = st.sidebar.file_uploader("Choose a file", type=['avi','wmv','mov','mp4','mkv'])
# Display GIF parameters once the file is loaded
if uploaded_file is not None:
# Saving to temporary file
tfile = tempfile.NamedTemporaryFile(delete=False)
tfile.write(uploaded_file.read())
## Open file ##
clip = VideoFileClip(tfile.name)
st.session_state.clip_duration = clip.duration
# Sidebar widgets
st.sidebar.header('Input parameters')
selected_resolution_scaling = st.sidebar.slider('Scaling of video resolution', 0.0, 2.0, 0.5 )
selected_speedx = st.sidebar.slider('Playback speed', 0.1, 10.0, 2.0)
selected_export_range = st.sidebar.slider('Duration range to export in seconds', 0, int(st.session_state.clip_duration), (0, int(st.session_state.clip_duration) ))
## Resizing of video
clip = clip.resize(selected_resolution_scaling)
st.session_state.clip_width = clip.w
st.session_state.clip_height = clip.h
st.session_state.clip_duration = clip.duration
st.session_state.clip_total_frames = clip.duration * clip.fps
st.session_state.clip_fps = st.sidebar.slider('FPS', 10, 60, 20)
## Display output
st.subheader('Metrics')
col1, col2, col3, col4, col5 = st.columns(5)
col1.metric('Width', st.session_state.clip_width, 'pixels')
col2.metric('Height', st.session_state.clip_height, 'pixels')
col3.metric('Duration', st.session_state.clip_duration, 'seconds')
col4.metric('FPS', st.session_state.clip_fps, '')
col5.metric('Total Frames', st.session_state.clip_total_frames, 'frames')
# Extract video frame as a display image
st.subheader('Preview')
with st.expander('Show image'):
selected_frame = st.slider('Preview a time frame (s)', 0, int(st.session_state.clip_duration), int(np.median(st.session_state.clip_duration)) )
clip.save_frame('frame.gif', t=selected_frame)
frame_image = Image.open('frame.gif')
st.image(frame_image)
## Print image parameters ##
st.subheader('Image parameters')
with st.expander('Show image parameters'):
st.write(f'File name: `{uploaded_file.name}`')
st.write('Image size:', frame_image.size)
st.write('Video resolution scaling', selected_resolution_scaling)
st.write('Speed playback:', selected_speedx)
st.write('Export duration:', selected_export_range)
st.write('Frames per second (FPS):', st.session_state.clip_fps)
## Export animated GIF ##
st.subheader('Generate GIF')
generate_gif = st.button('Generate Animated GIF')
if generate_gif:
clip = clip.subclip(selected_export_range[0], selected_export_range[1]).speedx(selected_speedx)
frames = []
for frame in clip.iter_frames():
frames.append(np.array(frame))
image_list = []
for frame in frames:
im = Image.fromarray(frame)
image_list.append(im)
image_list[0].save('export.gif', format = 'GIF', save_all = True, loop = 0, append_images = image_list)
## Download ##
st.subheader('Download')
file_ = open('export.gif', 'rb')
contents = file_.read()
data_url = base64.b64encode(contents).decode("utf-8")
file_.close()
st.markdown(
f'<img src="data:image/gif;base64,{data_url}" alt="cat gif">',
unsafe_allow_html=True,
)
fsize = round(os.path.getsize('export.gif')/(1024*1024), 1)
st.info(f'File size of generated GIF: {fsize} MB', icon='💾')
fname = uploaded_file.name.split('.')[0]
with open('export.gif', 'rb') as file:
btn = st.download_button(
label='Download image',
data=file,
file_name=f'{fname}_scaling-{selected_resolution_scaling}_fps-{st.session_state.clip_fps}_speed-{selected_speedx}_duration-{selected_export_range[0]}-{selected_export_range[1]}.gif',
mime='image/gif'
)
## Default page ##
else:
st.warning('👈 Upload your video file')