dennisvdang commited on
Commit
083c84b
·
1 Parent(s): 2836474

Script fixes

Browse files
Files changed (2) hide show
  1. app.py +14 -14
  2. style.css +24 -0
app.py CHANGED
@@ -316,32 +316,31 @@ def smooth_predictions(data: np.ndarray) -> np.ndarray:
316
 
317
  return smoothed_data
318
 
 
 
 
 
319
  def make_predictions(model, processed_audio, audio_features, url, video_name):
320
  predictions = model.predict(processed_audio)[0]
321
- binary_predictions = np.round(
322
- predictions[:(len(audio_features.meter_grid) - 1)]).flatten()
323
  smoothed_predictions = smooth_predictions(binary_predictions)
324
 
325
- meter_grid_times = librosa.frames_to_time(
326
- audio_features.meter_grid, sr=audio_features.sr, hop_length=audio_features.hop_length)
327
- chorus_start_times = [meter_grid_times[i] for i in range(len(
328
- smoothed_predictions)) if smoothed_predictions[i] == 1 and (i == 0 or smoothed_predictions[i - 1] == 0)]
329
- chorus_end_times = [meter_grid_times[i + 1] for i in range(len(
330
- smoothed_predictions)) if smoothed_predictions[i] == 1 and (i == len(smoothed_predictions) - 1 or smoothed_predictions[i + 1] == 0)]
331
 
332
  st.write(f"**Video Title:** {video_name}")
333
  st.write(f"**Number of choruses identified:** {len(chorus_start_times)}")
334
 
335
  for start_time, end_time in zip(chorus_start_times, chorus_end_times):
336
  link = f"{url}&t={int(start_time)}s"
337
- st.write(f"Chorus from {start_time:.2f}s to {end_time:.2f}s: [Link]({link})")
338
 
339
  if len(chorus_start_times) == 0:
340
  st.write("No choruses identified.")
341
 
342
  return smoothed_predictions
343
 
344
-
345
  def plot_meter_lines(ax: plt.Axes, meter_grid_times: np.ndarray) -> None:
346
  for time in meter_grid_times:
347
  ax.axvline(x=time, color='grey', linestyle='--',
@@ -393,15 +392,16 @@ def plot_predictions(audio_features, predictions):
393
 
394
 
395
  def main():
396
- st.title("Chorus Detection")
 
397
  st.write("Upload a YouTube URL to find the chorus in the song.")
398
  url = st.text_input("YouTube URL")
399
  if st.button("Find Chorus"):
400
  if url:
401
- with st.spinner('Extracting audio...'):
402
  audio_file, video_title, temp_dir = extract_audio(url)
403
  if audio_file:
404
- with st.spinner('Stripping silence...'):
405
  strip_silence(audio_file)
406
  with st.spinner('Processing audio...'):
407
  processed_audio, audio_features = process_audio(audio_path=audio_file)
@@ -416,4 +416,4 @@ def main():
416
  st.error("Please enter a valid YouTube URL")
417
 
418
  if __name__ == "__main__":
419
- main()
 
316
 
317
  return smoothed_data
318
 
319
+ def format_time(seconds):
320
+ m, s = divmod(seconds, 60)
321
+ return f"{int(m)}:{s:05.2f}"
322
+
323
  def make_predictions(model, processed_audio, audio_features, url, video_name):
324
  predictions = model.predict(processed_audio)[0]
325
+ binary_predictions = np.round(predictions[:(len(audio_features.meter_grid) - 1)]).flatten()
 
326
  smoothed_predictions = smooth_predictions(binary_predictions)
327
 
328
+ meter_grid_times = librosa.frames_to_time(audio_features.meter_grid, sr=audio_features.sr, hop_length=audio_features.hop_length)
329
+ chorus_start_times = [meter_grid_times[i] for i in range(len(smoothed_predictions)) if smoothed_predictions[i] == 1 and (i == 0 or smoothed_predictions[i - 1] == 0)]
330
+ chorus_end_times = [meter_grid_times[i + 1] for i in range(len(smoothed_predictions)) if smoothed_predictions[i] == 1 and (i == len(smoothed_predictions) - 1 or smoothed_predictions[i + 1] == 0)]
 
 
 
331
 
332
  st.write(f"**Video Title:** {video_name}")
333
  st.write(f"**Number of choruses identified:** {len(chorus_start_times)}")
334
 
335
  for start_time, end_time in zip(chorus_start_times, chorus_end_times):
336
  link = f"{url}&t={int(start_time)}s"
337
+ st.write(f"Chorus from {format_time(start_time)} to {format_time(end_time)}: [{link}]({link})")
338
 
339
  if len(chorus_start_times) == 0:
340
  st.write("No choruses identified.")
341
 
342
  return smoothed_predictions
343
 
 
344
  def plot_meter_lines(ax: plt.Axes, meter_grid_times: np.ndarray) -> None:
345
  for time in meter_grid_times:
346
  ax.axvline(x=time, color='grey', linestyle='--',
 
392
 
393
 
394
  def main():
395
+ st.title("Chorus Finder")
396
+ st.write("This app uses a pre-trained convolutional recurrent neural network to predict chorus locations in music. To learn more about this project, visit [github.com/dennisvdang/chorus-detection](https://github.com/dennisvdang/chorus-detection).")
397
  st.write("Upload a YouTube URL to find the chorus in the song.")
398
  url = st.text_input("YouTube URL")
399
  if st.button("Find Chorus"):
400
  if url:
401
+ with st.spinner('Analyzing YouTube link...'):
402
  audio_file, video_title, temp_dir = extract_audio(url)
403
  if audio_file:
404
+ with st.spinner('Trimming silence...'):
405
  strip_silence(audio_file)
406
  with st.spinner('Processing audio...'):
407
  processed_audio, audio_features = process_audio(audio_path=audio_file)
 
416
  st.error("Please enter a valid YouTube URL")
417
 
418
  if __name__ == "__main__":
419
+ main()
style.css ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ /* background-image: url('https://your-image-url.com/background.jpg'); */
3
+ background-size: cover;
4
+ }
5
+
6
+ .stButton>button {
7
+ background-color: #fcb900;
8
+ color: white;
9
+ border: none;
10
+ padding: 10px 24px;
11
+ text-align: center;
12
+ text-decoration: none;
13
+ display: inline-block;
14
+ font-size: 16px;
15
+ margin: 4px 2px;
16
+ transition-duration: 0.4s;
17
+ cursor: pointer;
18
+ }
19
+
20
+ .stButton>button:hover {
21
+ background-color: white;
22
+ color: black;
23
+ border: 2px solid #4CAF50;
24
+ }