ahk-d commited on
Commit
8814906
Β·
verified Β·
1 Parent(s): 763d88e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -47
app.py CHANGED
@@ -1,90 +1,75 @@
1
  # app.py
2
 
3
- # 2. Import Libraries
4
  import gradio as gr
5
  import torch
6
  import torchaudio
7
  from demucs.pretrained import get_model
8
  from demucs.apply import apply_model
9
  import os
10
- import time
11
 
12
- # 3. Setup the Model
13
- # This section sets up the device (GPU if available) and loads the pre-trained HT Demucs model.
14
  print("Setting up the model...")
15
  device = 'cuda' if torch.cuda.is_available() else 'cpu'
16
  print(f"Using device: {device}")
17
 
18
- # Load the pre-trained HTDemucs model
19
- # To make this work on Hugging Face, we'll download the model weights to a cache folder.
20
- # The `get_model` function handles this automatically.
21
  model = get_model(name="htdemucs")
22
  model = model.to(device)
23
  model.eval()
24
  print("Model loaded successfully.")
25
 
26
- # 4. Define the Separation Function
 
 
 
 
 
 
27
  def separate_stems(audio_path):
28
  """
29
- This function takes an audio file path, separates it into stems,
30
- and returns the paths to the separated audio files.
31
  """
32
  if audio_path is None:
33
  return None, None, None, None, "Please upload an audio file."
34
 
35
  try:
36
  print(f"Loading audio from: {audio_path}")
37
- # Load the audio file
38
  wav, sr = torchaudio.load(audio_path)
39
 
40
- # Ensure the audio is stereo
41
  if wav.shape[0] == 1:
42
  print("Audio is mono, converting to stereo.")
43
  wav = wav.repeat(2, 1)
44
 
45
- # Move tensor to the correct device
46
  wav = wav.to(device)
47
 
48
- # Apply the separation model
49
  print("Applying the separation model...")
50
  with torch.no_grad():
51
- # The apply_model function expects a batch, so we add a dimension
52
  sources = apply_model(model, wav[None], device=device, progress=True)[0]
53
  print("Separation complete.")
54
 
55
- # Define stem names
56
  stem_names = ["drums", "bass", "other", "vocals"]
57
-
58
- # Create a directory to save the output files
59
- # It's good practice to use a temporary directory for each session
60
- # or a unique folder to avoid conflicts in a multi-user environment
61
  output_dir = "separated_stems"
62
  os.makedirs(output_dir, exist_ok=True)
63
 
64
- # Save each stem and collect their paths
65
- output_paths = []
66
  for i, name in enumerate(stem_names):
67
  out_path = os.path.join(output_dir, f"{name}.wav")
68
  torchaudio.save(out_path, sources[i].cpu(), sr)
69
- output_paths.append(out_path)
70
- print(f"Saved {name} stem to {out_path}")
71
 
72
- # Return the paths to the separated audio files
73
- return output_paths[0], output_paths[1], output_paths[2], output_paths[3], "Separation successful!"
74
 
75
  except Exception as e:
76
- print(f"An error occurred: {e}")
77
- return None, None, None, None, f"An error occurred: {str(e)}"
78
 
79
- # 5. Create the Gradio Interface
80
  print("Creating Gradio interface...")
81
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
82
- gr.Markdown(
83
- """
84
- # 🎡 Music Stem Separator with HT Demucs
85
- Upload your song (in .wav or .mp3 format) and the model will separate it into four stems: **Drums**, **Bass**, **Other**, and **Vocals**.
86
- """
87
- )
88
 
89
  with gr.Row():
90
  with gr.Column():
@@ -93,7 +78,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
93
  status_output = gr.Textbox(label="Status", interactive=False)
94
 
95
  with gr.Column():
96
- gr.Markdown("### Separated Stems")
97
  drums_output = gr.Audio(label="Drums", type="filepath")
98
  bass_output = gr.Audio(label="Bass", type="filepath")
99
  other_output = gr.Audio(label="Other", type="filepath")
@@ -105,15 +90,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
105
  outputs=[drums_output, bass_output, other_output, vocals_output, status_output]
106
  )
107
 
108
- gr.Markdown(
109
- """
110
- ---
111
- <p style='text-align: center; font-size: small;'>
112
- Powered by <a href='https://github.com/facebookresearch/demucs' target='_blank'>HT Demucs</a>.
113
- </p>
114
- """
115
- )
116
 
117
- # 6. Launch the Gradio App
118
- # The launch command should be at the end of the script
119
- demo.launch()
 
1
  # app.py
2
 
 
3
  import gradio as gr
4
  import torch
5
  import torchaudio
6
  from demucs.pretrained import get_model
7
  from demucs.apply import apply_model
8
  import os
9
+ import base64
10
 
11
+ # --- Setup the model ---
 
12
  print("Setting up the model...")
13
  device = 'cuda' if torch.cuda.is_available() else 'cpu'
14
  print(f"Using device: {device}")
15
 
 
 
 
16
  model = get_model(name="htdemucs")
17
  model = model.to(device)
18
  model.eval()
19
  print("Model loaded successfully.")
20
 
21
+ # --- Helper function to convert WAV to base64 data URI ---
22
+ def file_to_data_uri(path):
23
+ with open(path, "rb") as f:
24
+ data = f.read()
25
+ return f"data:audio/wav;base64,{base64.b64encode(data).decode()}"
26
+
27
+ # --- Separation function ---
28
  def separate_stems(audio_path):
29
  """
30
+ Separates an audio file into drums, bass, other, and vocals.
31
+ Returns base64-encoded audio URIs for frontend playback.
32
  """
33
  if audio_path is None:
34
  return None, None, None, None, "Please upload an audio file."
35
 
36
  try:
37
  print(f"Loading audio from: {audio_path}")
 
38
  wav, sr = torchaudio.load(audio_path)
39
 
 
40
  if wav.shape[0] == 1:
41
  print("Audio is mono, converting to stereo.")
42
  wav = wav.repeat(2, 1)
43
 
 
44
  wav = wav.to(device)
45
 
 
46
  print("Applying the separation model...")
47
  with torch.no_grad():
 
48
  sources = apply_model(model, wav[None], device=device, progress=True)[0]
49
  print("Separation complete.")
50
 
51
+ # Save stems temporarily & encode to base64 URIs
52
  stem_names = ["drums", "bass", "other", "vocals"]
 
 
 
 
53
  output_dir = "separated_stems"
54
  os.makedirs(output_dir, exist_ok=True)
55
 
56
+ output_uris = []
 
57
  for i, name in enumerate(stem_names):
58
  out_path = os.path.join(output_dir, f"{name}.wav")
59
  torchaudio.save(out_path, sources[i].cpu(), sr)
60
+ output_uris.append(file_to_data_uri(out_path))
61
+ print(f"Encoded {name} to base64 URI")
62
 
63
+ return output_uris[0], output_uris[1], output_uris[2], output_uris[3], "βœ… Separation successful!"
 
64
 
65
  except Exception as e:
66
+ print(f"Error: {e}")
67
+ return None, None, None, None, f"❌ Error: {str(e)}"
68
 
69
+ # --- Gradio UI ---
70
  print("Creating Gradio interface...")
71
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
72
+ gr.Markdown("# 🎡 Music Stem Separator with HT Demucs")
 
 
 
 
 
73
 
74
  with gr.Row():
75
  with gr.Column():
 
78
  status_output = gr.Textbox(label="Status", interactive=False)
79
 
80
  with gr.Column():
81
+ gr.Markdown("### 🎧 Separated Stems")
82
  drums_output = gr.Audio(label="Drums", type="filepath")
83
  bass_output = gr.Audio(label="Bass", type="filepath")
84
  other_output = gr.Audio(label="Other", type="filepath")
 
90
  outputs=[drums_output, bass_output, other_output, vocals_output, status_output]
91
  )
92
 
93
+ gr.Markdown("---\n<p style='text-align: center; font-size: small;'>Powered by HT Demucs</p>")
 
 
 
 
 
 
 
94
 
95
+ # βœ… Enable API for Next.js
96
+ demo.launch(share=True)