Spaces:
Running
Running
ziqiangao
commited on
Commit
·
3526004
1
Parent(s):
2976e81
add external metadata input and group inputs
Browse files
app.py
CHANGED
@@ -26,11 +26,6 @@ def safe_read(i: int, a: list):
|
|
26 |
else:
|
27 |
return a[i]
|
28 |
|
29 |
-
def getTrigger(ad: int, a: list, max: int = 1024) -> int:
|
30 |
-
i = ad
|
31 |
-
while not (a[i] < 126 and not a[i + 4] < 130 or i - ad > max):
|
32 |
-
i += 1
|
33 |
-
return i
|
34 |
|
35 |
def getRenderCords(ta: list, idx: int, res: int = 1024, size: tuple = (1280, 720)) -> list:
|
36 |
i = idx - res // 2
|
@@ -54,14 +49,13 @@ def totopleft(coord, width=1280, height=720):
|
|
54 |
|
55 |
def getTrigger(ad: int, a: list, max: int = 1024) -> int:
|
56 |
i = ad
|
57 |
-
while not (safe_read(i,a) <
|
58 |
i += 1
|
59 |
return i
|
60 |
|
61 |
def extract_cover_image(mp3_file):
|
62 |
audio = MP3(mp3_file, ID3=ID3)
|
63 |
if audio.tags == None:
|
64 |
-
|
65 |
return -1
|
66 |
for tag in audio.tags.values():
|
67 |
if isinstance(tag, APIC):
|
@@ -73,8 +67,8 @@ def extract_cover_image(mp3_file):
|
|
73 |
|
74 |
def getTitleAndArtist(mp3_file):
|
75 |
audio = MP3(mp3_file, ID3=ID3)
|
76 |
-
title = audio.get('TIT2', TIT2(encoding=3, text='
|
77 |
-
artist = audio.get('TPE1', TPE1(encoding=3, text='
|
78 |
|
79 |
|
80 |
return title, artist
|
@@ -176,7 +170,7 @@ def stripinvisibles(s):
|
|
176 |
e.replace(i,"")
|
177 |
return e
|
178 |
|
179 |
-
def main(file, name, fps=30, res: tuple=(1280,720), oscres=512, sr=11025, lyrics=None):
|
180 |
p = gr.Progress()
|
181 |
LRC2SRT.clear()
|
182 |
if os.path.exists("out.srt"):
|
@@ -201,7 +195,7 @@ def main(file, name, fps=30, res: tuple=(1280,720), oscres=512, sr=11025, lyrics
|
|
201 |
gr.Warning("Lyrics file is invalid, skipping")
|
202 |
except Exception as e:
|
203 |
print(traceback.format_exc())
|
204 |
-
gr.Warning("Failed to parse lyrics, ensure there are no blank lines in between
|
205 |
|
206 |
os.makedirs(path+f'out/{name}/', exist_ok=True)
|
207 |
global iii
|
@@ -214,18 +208,25 @@ def main(file, name, fps=30, res: tuple=(1280,720), oscres=512, sr=11025, lyrics
|
|
214 |
samples_array = y_u8.tolist()
|
215 |
p(0.5,"extracting metadata")
|
216 |
# Extract cover image, title, and artist
|
|
|
|
|
|
|
217 |
cover_img = extract_cover_image(audio_path)
|
218 |
-
if cover_img
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
|
|
224 |
|
225 |
|
226 |
title, artist = getTitleAndArtist(audio_path)
|
227 |
-
if title == '
|
228 |
-
|
|
|
|
|
|
|
229 |
dominant_color = getColour(cover_img)
|
230 |
|
231 |
# Frame rendering parameters
|
@@ -247,7 +248,7 @@ def main(file, name, fps=30, res: tuple=(1280,720), oscres=512, sr=11025, lyrics
|
|
247 |
|
248 |
except Exception as e:
|
249 |
print('Ended in error: ' + traceback.format_exc(), iii)
|
250 |
-
|
251 |
p = gr.Progress()
|
252 |
p(0.5,desc="Compiling video")
|
253 |
print('FFMPEG')
|
@@ -281,28 +282,53 @@ def main(file, name, fps=30, res: tuple=(1280,720), oscres=512, sr=11025, lyrics
|
|
281 |
]
|
282 |
subprocess.run(ffmpeg_cmd)
|
283 |
|
284 |
-
def gradio_interface(audio_file, lyrics, output_name, fps=30, vidwidth=1280, vidheight=720, oscres=512,
|
285 |
resolution = f"{vidwidth}x{vidheight}"
|
286 |
res = tuple(map(int, resolution.split('x')))
|
287 |
-
main(audio_file, output_name, fps=fps, res=res, oscres=oscres,
|
288 |
time.sleep(5)
|
289 |
|
290 |
shutil.rmtree("out")
|
291 |
return f"{output_name}.mp4"
|
292 |
|
293 |
-
# Define Gradio interface with
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
iface = gr.Interface(
|
295 |
fn=gradio_interface,
|
296 |
-
inputs=
|
297 |
-
gr.components.File(label="Upload your MP3 file", file_count='single', file_types=['mp3']),
|
298 |
-
gr.components.File(label="(Optional) Upload Lyrics as LRC or SRT", file_count='single', file_types=['lrc','srt']),
|
299 |
-
gr.components.Textbox(label="Output Video Name", value='video'),
|
300 |
-
gr.components.Slider(label="Frames per Second", minimum=20, maximum=60, step=1, value=30),
|
301 |
-
gr.components.Slider(label="Output Video Width", minimum=100, maximum=2000, value=1280, step=2),
|
302 |
-
gr.components.Slider(label="Output Video Height", minimum=100, maximum=2000, value=720, step=2),
|
303 |
-
gr.components.Slider(label="Number of Visualization Segments", minimum=256, maximum=2048, step=2, value=512),
|
304 |
-
#gr.components.Slider(label="Scope Sample Rate", minimum=8000, maximum=44100, step=5, value=11025)
|
305 |
-
],
|
306 |
outputs=gr.components.Video(label="Output"),
|
307 |
title="MP3 to Video Visualization",
|
308 |
description=""" Upload an MP3 file and configure parameters to create a visualization video.
|
@@ -311,4 +337,4 @@ iface = gr.Interface(
|
|
311 |
)
|
312 |
|
313 |
# Launch Gradio interface
|
314 |
-
iface.launch()
|
|
|
26 |
else:
|
27 |
return a[i]
|
28 |
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
def getRenderCords(ta: list, idx: int, res: int = 1024, size: tuple = (1280, 720)) -> list:
|
31 |
i = idx - res // 2
|
|
|
49 |
|
50 |
def getTrigger(ad: int, a: list, max: int = 1024) -> int:
|
51 |
i = ad
|
52 |
+
while not (safe_read(i,a) < 126 and safe_read(i+6,a) < 130 or i - ad > max):
|
53 |
i += 1
|
54 |
return i
|
55 |
|
56 |
def extract_cover_image(mp3_file):
|
57 |
audio = MP3(mp3_file, ID3=ID3)
|
58 |
if audio.tags == None:
|
|
|
59 |
return -1
|
60 |
for tag in audio.tags.values():
|
61 |
if isinstance(tag, APIC):
|
|
|
67 |
|
68 |
def getTitleAndArtist(mp3_file):
|
69 |
audio = MP3(mp3_file, ID3=ID3)
|
70 |
+
title = audio.get('TIT2', TIT2(encoding=3, text='')).text[0]
|
71 |
+
artist = audio.get('TPE1', TPE1(encoding=3, text='')).text[0]
|
72 |
|
73 |
|
74 |
return title, artist
|
|
|
170 |
e.replace(i,"")
|
171 |
return e
|
172 |
|
173 |
+
def main(file, name, fps=30, res: tuple=(1280,720), oscres=512, sr=11025, lyrics=None, img=None, tit=None, ast=None):
|
174 |
p = gr.Progress()
|
175 |
LRC2SRT.clear()
|
176 |
if os.path.exists("out.srt"):
|
|
|
195 |
gr.Warning("Lyrics file is invalid, skipping")
|
196 |
except Exception as e:
|
197 |
print(traceback.format_exc())
|
198 |
+
gr.Warning("Failed to parse lyrics, ensure there are no blank lines in between")
|
199 |
|
200 |
os.makedirs(path+f'out/{name}/', exist_ok=True)
|
201 |
global iii
|
|
|
208 |
samples_array = y_u8.tolist()
|
209 |
p(0.5,"extracting metadata")
|
210 |
# Extract cover image, title, and artist
|
211 |
+
cover_file = None
|
212 |
+
if img:
|
213 |
+
cover_file = Image.open(img)
|
214 |
cover_img = extract_cover_image(audio_path)
|
215 |
+
if cover_img == None:
|
216 |
+
if img:
|
217 |
+
cover_img = cover_file
|
218 |
+
else:
|
219 |
+
raise gr.Error("Mp3 must have a cover image, upload the image under the 'Metadata' section")
|
220 |
+
elif cover_img == -1 and not (tit or ast):
|
221 |
+
raise gr.Error("Mp3 is missing tags, add the info under the 'Metadata' section")
|
222 |
|
223 |
|
224 |
title, artist = getTitleAndArtist(audio_path)
|
225 |
+
if title == '' or artist == '':
|
226 |
+
if not (tit or ast):
|
227 |
+
gr.Warning('Missing Title or Artist')
|
228 |
+
else:
|
229 |
+
title, artist = tit, ast
|
230 |
dominant_color = getColour(cover_img)
|
231 |
|
232 |
# Frame rendering parameters
|
|
|
248 |
|
249 |
except Exception as e:
|
250 |
print('Ended in error: ' + traceback.format_exc(), iii)
|
251 |
+
gr.e
|
252 |
p = gr.Progress()
|
253 |
p(0.5,desc="Compiling video")
|
254 |
print('FFMPEG')
|
|
|
282 |
]
|
283 |
subprocess.run(ffmpeg_cmd)
|
284 |
|
285 |
+
def gradio_interface(audio_file, lyrics, output_name, fps=30, vidwidth=1280, vidheight=720, oscres=512, img=None, tit=None, ast=None):
|
286 |
resolution = f"{vidwidth}x{vidheight}"
|
287 |
res = tuple(map(int, resolution.split('x')))
|
288 |
+
main(audio_file, output_name, fps=fps, res=res, oscres=oscres, lyrics=lyrics, img=img, tit=tit, ast=ast)
|
289 |
time.sleep(5)
|
290 |
|
291 |
shutil.rmtree("out")
|
292 |
return f"{output_name}.mp4"
|
293 |
|
294 |
+
# Define Gradio interface with accordions
|
295 |
+
inputs = [
|
296 |
+
gr.Accordion(
|
297 |
+
title="Audio Settings",
|
298 |
+
items=[
|
299 |
+
gr.components.File(label="Upload your MP3 file", file_count='single', file_types=['mp3']),
|
300 |
+
gr.components.File(label="(Optional) Upload Lyrics as LRC or SRT", file_count='single', file_types=['lrc','srt'])
|
301 |
+
],
|
302 |
+
open=True
|
303 |
+
),
|
304 |
+
gr.Accordion(
|
305 |
+
title="Video Output Settings",
|
306 |
+
items=[
|
307 |
+
gr.components.Textbox(label="Output Video Name", value='video'),
|
308 |
+
gr.components.Slider(label="Frames per Second", minimum=20, maximum=60, step=1, value=30),
|
309 |
+
gr.components.Slider(label="Output Video Width", minimum=100, maximum=2000, value=1280, step=2),
|
310 |
+
gr.components.Slider(label="Output Video Height", minimum=100, maximum=2000, value=720, step=2)
|
311 |
+
]
|
312 |
+
),
|
313 |
+
gr.Accordion(
|
314 |
+
title="Advanced Options",
|
315 |
+
items=[
|
316 |
+
gr.components.Slider(label="Number of Visualization Segments", minimum=256, maximum=2048, step=2, value=512),
|
317 |
+
]
|
318 |
+
),
|
319 |
+
gr.Accordion(
|
320 |
+
title="Mp3 Metadata (Use if mp3 does not have tags)",
|
321 |
+
items=[
|
322 |
+
gr.components.Image(label='Cover Art'),
|
323 |
+
gr.components.Textbox(label='Title'),
|
324 |
+
gr.components.Textbox(label='Artists')
|
325 |
+
]
|
326 |
+
)
|
327 |
+
]
|
328 |
+
|
329 |
iface = gr.Interface(
|
330 |
fn=gradio_interface,
|
331 |
+
inputs=inputs,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
332 |
outputs=gr.components.Video(label="Output"),
|
333 |
title="MP3 to Video Visualization",
|
334 |
description=""" Upload an MP3 file and configure parameters to create a visualization video.
|
|
|
337 |
)
|
338 |
|
339 |
# Launch Gradio interface
|
340 |
+
iface.launch()
|