ziqiangao commited on
Commit
3526004
·
1 Parent(s): 2976e81

add external metadata input and group inputs

Browse files
Files changed (1) hide show
  1. app.py +60 -34
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) < 124 and safe_read(i+2,a) < 128 or i - ad > max):
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='Unknown Title')).text[0]
77
- artist = audio.get('TPE1', TPE1(encoding=3, text='Unknown Artist')).text[0]
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 and invisible characters")
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 is None:
219
- raise gr.Error("Mp3 must have a cover image")
220
- return # Exit if no cover image found
221
- elif cover_img == -1:
222
- raise gr.Error("Mp3 is missing tags")
223
- return
 
224
 
225
 
226
  title, artist = getTitleAndArtist(audio_path)
227
- if title == 'Unknown Title' or artist == 'Unknown Artist':
228
- gr.Warning('Missing Title or Artist')
 
 
 
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
- #gr.Info("Rendering had errored, this typically an out of range error")
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, sr=11025):
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, sr=sr, lyrics=lyrics)
288
  time.sleep(5)
289
 
290
  shutil.rmtree("out")
291
  return f"{output_name}.mp4"
292
 
293
- # Define Gradio interface with progress bar
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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()