sourav-das commited on
Commit
a0f35dd
·
verified ·
1 Parent(s): 7dfae77

Upload folder using huggingface_hub

Browse files
backend/__pycache__/main.cpython-313.pyc CHANGED
Binary files a/backend/__pycache__/main.cpython-313.pyc and b/backend/__pycache__/main.cpython-313.pyc differ
 
backend/examples/default/README.md CHANGED
@@ -1,4 +1,5 @@
1
  Place the bundled example audio files for the demo flow in this directory.
 
2
 
3
  Expected filenames:
4
 
 
1
  Place the bundled example audio files for the demo flow in this directory.
2
+ Song: Satelites - Periphery
3
 
4
  Expected filenames:
5
 
backend/main.py CHANGED
@@ -22,6 +22,7 @@ app = FastAPI(title="Stem Separator")
22
  MAX_UPLOAD_SIZE = 100 * 1024 * 1024 # 100MB
23
  EXAMPLE_NAME = "default"
24
  EXAMPLE_DIR = Path(__file__).parent / "examples" / EXAMPLE_NAME
 
25
  EXAMPLE_ORIGINAL_FILE = "original.mp3"
26
  EXAMPLE_STEM_FILES = {
27
  "Vocals": "Vocals.mp3",
@@ -188,6 +189,7 @@ async def delete_job(job_id: str):
188
  @app.get("/api/examples/default")
189
  async def get_example_output():
190
  original_path = get_example_file(EXAMPLE_ORIGINAL_FILE, allow_original=True)
 
191
  stems = []
192
  for stem_name, filename in EXAMPLE_STEM_FILES.items():
193
  stem_path = get_example_file(filename)
@@ -201,9 +203,11 @@ async def get_example_output():
201
  )
202
 
203
  return {
 
204
  "original": {
205
  "filename": original_path.name,
206
  "audioUrl": f"/api/examples/{EXAMPLE_NAME}/audio/{original_path.name}",
 
207
  },
208
  "stems": stems,
209
  "downloadAllUrl": f"/api/examples/{EXAMPLE_NAME}/download/all",
@@ -269,3 +273,17 @@ def get_example_file(filename: str, allow_original: bool = False) -> Path:
269
  raise HTTPException(404, f"Missing example asset: {filename}")
270
 
271
  return path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  MAX_UPLOAD_SIZE = 100 * 1024 * 1024 # 100MB
23
  EXAMPLE_NAME = "default"
24
  EXAMPLE_DIR = Path(__file__).parent / "examples" / EXAMPLE_NAME
25
+ EXAMPLE_README = EXAMPLE_DIR / "README.md"
26
  EXAMPLE_ORIGINAL_FILE = "original.mp3"
27
  EXAMPLE_STEM_FILES = {
28
  "Vocals": "Vocals.mp3",
 
189
  @app.get("/api/examples/default")
190
  async def get_example_output():
191
  original_path = get_example_file(EXAMPLE_ORIGINAL_FILE, allow_original=True)
192
+ song_name = get_example_song_name()
193
  stems = []
194
  for stem_name, filename in EXAMPLE_STEM_FILES.items():
195
  stem_path = get_example_file(filename)
 
203
  )
204
 
205
  return {
206
+ "song": song_name,
207
  "original": {
208
  "filename": original_path.name,
209
  "audioUrl": f"/api/examples/{EXAMPLE_NAME}/audio/{original_path.name}",
210
+ "songName": song_name,
211
  },
212
  "stems": stems,
213
  "downloadAllUrl": f"/api/examples/{EXAMPLE_NAME}/download/all",
 
273
  raise HTTPException(404, f"Missing example asset: {filename}")
274
 
275
  return path
276
+
277
+
278
+ def get_example_song_name() -> str:
279
+ default_name = "Example Song"
280
+ if not EXAMPLE_README.exists():
281
+ return default_name
282
+
283
+ for line in EXAMPLE_README.read_text(encoding="utf-8").splitlines():
284
+ if line.lower().startswith("song:"):
285
+ value = line.split(":", 1)[1].strip()
286
+ if value:
287
+ return value
288
+
289
+ return default_name
frontend/src/App.tsx CHANGED
@@ -88,6 +88,7 @@ export default function App() {
88
  <OriginalTrack
89
  url={state.originalUrl}
90
  filename={state.filename}
 
91
  />
92
  <OutputFormatSelector
93
  value={state.outputFormat}
@@ -119,6 +120,7 @@ export default function App() {
119
  <OriginalTrack
120
  url={state.originalUrl}
121
  filename={state.filename}
 
122
  />
123
  <StemResults
124
  stems={state.stems}
@@ -133,6 +135,7 @@ export default function App() {
133
  <OriginalTrack
134
  url={state.original.audioUrl}
135
  filename={state.original.filename}
 
136
  />
137
  <StemResults
138
  stems={state.stems}
 
88
  <OriginalTrack
89
  url={state.originalUrl}
90
  filename={state.filename}
91
+ songName={state.songName}
92
  />
93
  <OutputFormatSelector
94
  value={state.outputFormat}
 
120
  <OriginalTrack
121
  url={state.originalUrl}
122
  filename={state.filename}
123
+ songName={state.songName}
124
  />
125
  <StemResults
126
  stems={state.stems}
 
135
  <OriginalTrack
136
  url={state.original.audioUrl}
137
  filename={state.original.filename}
138
+ songName={state.original.songName}
139
  />
140
  <StemResults
141
  stems={state.stems}
frontend/src/api.ts CHANGED
@@ -168,6 +168,7 @@ export function subscribeProgress(
168
  }
169
 
170
  export interface ExampleOutputResponse {
 
171
  original: OriginalTrackAsset;
172
  stems: StemAsset[];
173
  downloadAllUrl: string;
 
168
  }
169
 
170
  export interface ExampleOutputResponse {
171
+ song?: string;
172
  original: OriginalTrackAsset;
173
  stems: StemAsset[];
174
  downloadAllUrl: string;
frontend/src/components/OriginalTrack.tsx CHANGED
@@ -3,28 +3,37 @@ import { WaveformPlayer } from "./WaveformPlayer";
3
  interface OriginalTrackProps {
4
  url: string;
5
  filename: string;
 
6
  }
7
 
8
- export function OriginalTrack({ url, filename }: OriginalTrackProps) {
9
  return (
10
  <div className="bg-bg-card rounded-xl p-4 md:p-5">
11
- <div className="flex items-center gap-2 mb-3">
12
- <svg
13
- className="w-5 h-5 text-accent"
14
- fill="none"
15
- viewBox="0 0 24 24"
16
- stroke="currentColor"
17
- strokeWidth={2}
18
- >
19
- <path
20
- strokeLinecap="round"
21
- strokeLinejoin="round"
22
- d="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zM9 10l12-3"
23
- />
24
- </svg>
25
- <span className="text-sm font-medium text-text-primary truncate">
26
- {filename}
27
- </span>
 
 
 
 
 
 
 
 
28
  </div>
29
  <WaveformPlayer
30
  url={url}
 
3
  interface OriginalTrackProps {
4
  url: string;
5
  filename: string;
6
+ songName?: string;
7
  }
8
 
9
+ export function OriginalTrack({ url, filename, songName }: OriginalTrackProps) {
10
  return (
11
  <div className="bg-bg-card rounded-xl p-4 md:p-5">
12
+ <div className="mb-3 space-y-1.5">
13
+ <div className="flex items-center gap-2">
14
+ <svg
15
+ className="w-5 h-5 text-accent"
16
+ fill="none"
17
+ viewBox="0 0 24 24"
18
+ stroke="currentColor"
19
+ strokeWidth={2}
20
+ >
21
+ <path
22
+ strokeLinecap="round"
23
+ strokeLinejoin="round"
24
+ d="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zM9 10l12-3"
25
+ />
26
+ </svg>
27
+ <span className="text-sm font-medium text-text-primary truncate">
28
+ {filename}
29
+ </span>
30
+ </div>
31
+ {songName && (
32
+ <p className="text-sm text-text-secondary">
33
+ <span className="font-medium text-text-primary">Song:</span>{" "}
34
+ {songName}
35
+ </p>
36
+ )}
37
  </div>
38
  <WaveformPlayer
39
  url={url}
frontend/src/hooks/useSeparation.ts CHANGED
@@ -33,6 +33,7 @@ function reducer(state: AppState, action: AppAction): AppState {
33
  filename: action.filename,
34
  originalUrl: action.originalUrl,
35
  outputFormat: action.outputFormat,
 
36
  sourceKind: action.sourceKind,
37
  sourceUrl: action.sourceUrl,
38
  resolvedUrl: action.resolvedUrl,
@@ -49,6 +50,7 @@ function reducer(state: AppState, action: AppAction): AppState {
49
  filename: state.filename,
50
  originalUrl: state.originalUrl,
51
  outputFormat: state.outputFormat,
 
52
  sourceKind: state.sourceKind,
53
  sourceUrl: state.sourceUrl,
54
  resolvedUrl: state.resolvedUrl,
@@ -72,6 +74,7 @@ function reducer(state: AppState, action: AppAction): AppState {
72
  filename: state.filename,
73
  originalUrl: state.originalUrl,
74
  outputFormat: state.outputFormat,
 
75
  sourceKind: state.sourceKind,
76
  sourceUrl: state.sourceUrl,
77
  resolvedUrl: state.resolvedUrl,
@@ -118,6 +121,7 @@ export function useSeparation() {
118
  `input${getExtFromFilename(result.filename)}`
119
  ),
120
  outputFormat: getDefaultOutputFormat(result.filename),
 
121
  sourceKind: "file",
122
  });
123
  } catch (err) {
@@ -189,6 +193,7 @@ export function useSeparation() {
189
  `input${getExtFromFilename(result.filename)}`
190
  ),
191
  outputFormat: getDefaultOutputFormat(result.filename),
 
192
  sourceKind: result.platform,
193
  sourceUrl: result.source_url,
194
  resolvedUrl: result.resolved_url,
@@ -211,7 +216,10 @@ export function useSeparation() {
211
  const example = await fetchExampleOutput();
212
  dispatch({
213
  type: "LOAD_EXAMPLE_DONE",
214
- original: example.original,
 
 
 
215
  stems: example.stems,
216
  downloadAllUrl: example.downloadAllUrl,
217
  });
@@ -252,6 +260,11 @@ function getExtFromFilename(filename: string): string {
252
  return dot >= 0 ? filename.slice(dot) : ".wav";
253
  }
254
 
 
 
 
 
 
255
  function getDefaultOutputFormat(filename: string): OutputFormat {
256
  const ext = getExtFromFilename(filename).toLowerCase();
257
  if (ext === ".wav") return "wav";
 
33
  filename: action.filename,
34
  originalUrl: action.originalUrl,
35
  outputFormat: action.outputFormat,
36
+ songName: action.songName,
37
  sourceKind: action.sourceKind,
38
  sourceUrl: action.sourceUrl,
39
  resolvedUrl: action.resolvedUrl,
 
50
  filename: state.filename,
51
  originalUrl: state.originalUrl,
52
  outputFormat: state.outputFormat,
53
+ songName: state.songName,
54
  sourceKind: state.sourceKind,
55
  sourceUrl: state.sourceUrl,
56
  resolvedUrl: state.resolvedUrl,
 
74
  filename: state.filename,
75
  originalUrl: state.originalUrl,
76
  outputFormat: state.outputFormat,
77
+ songName: state.songName,
78
  sourceKind: state.sourceKind,
79
  sourceUrl: state.sourceUrl,
80
  resolvedUrl: state.resolvedUrl,
 
121
  `input${getExtFromFilename(result.filename)}`
122
  ),
123
  outputFormat: getDefaultOutputFormat(result.filename),
124
+ songName: stripExtension(result.filename),
125
  sourceKind: "file",
126
  });
127
  } catch (err) {
 
193
  `input${getExtFromFilename(result.filename)}`
194
  ),
195
  outputFormat: getDefaultOutputFormat(result.filename),
196
+ songName: result.title || stripExtension(result.filename),
197
  sourceKind: result.platform,
198
  sourceUrl: result.source_url,
199
  resolvedUrl: result.resolved_url,
 
216
  const example = await fetchExampleOutput();
217
  dispatch({
218
  type: "LOAD_EXAMPLE_DONE",
219
+ original: {
220
+ ...example.original,
221
+ songName: example.song || example.original.songName,
222
+ },
223
  stems: example.stems,
224
  downloadAllUrl: example.downloadAllUrl,
225
  });
 
260
  return dot >= 0 ? filename.slice(dot) : ".wav";
261
  }
262
 
263
+ function stripExtension(filename: string): string {
264
+ const dot = filename.lastIndexOf(".");
265
+ return dot >= 0 ? filename.slice(0, dot) : filename;
266
+ }
267
+
268
  function getDefaultOutputFormat(filename: string): OutputFormat {
269
  const ext = getExtFromFilename(filename).toLowerCase();
270
  if (ext === ".wav") return "wav";
frontend/src/types.ts CHANGED
@@ -10,6 +10,7 @@ export type InputMode = "upload" | "link";
10
  export interface OriginalTrackAsset {
11
  filename: string;
12
  audioUrl: string;
 
13
  }
14
 
15
  export interface StemAsset extends StemResult {
@@ -26,6 +27,7 @@ export type AppState =
26
  filename: string;
27
  originalUrl: string;
28
  outputFormat: OutputFormat;
 
29
  sourceKind: SourceKind;
30
  sourceUrl?: string;
31
  resolvedUrl?: string;
@@ -36,6 +38,7 @@ export type AppState =
36
  filename: string;
37
  originalUrl: string;
38
  outputFormat: OutputFormat;
 
39
  sourceKind: SourceKind;
40
  sourceUrl?: string;
41
  resolvedUrl?: string;
@@ -49,6 +52,7 @@ export type AppState =
49
  filename: string;
50
  originalUrl: string;
51
  outputFormat: OutputFormat;
 
52
  sourceKind: SourceKind;
53
  sourceUrl?: string;
54
  resolvedUrl?: string;
@@ -72,6 +76,7 @@ export type AppAction =
72
  filename: string;
73
  originalUrl: string;
74
  outputFormat: OutputFormat;
 
75
  sourceKind: SourceKind;
76
  sourceUrl?: string;
77
  resolvedUrl?: string;
 
10
  export interface OriginalTrackAsset {
11
  filename: string;
12
  audioUrl: string;
13
+ songName?: string;
14
  }
15
 
16
  export interface StemAsset extends StemResult {
 
27
  filename: string;
28
  originalUrl: string;
29
  outputFormat: OutputFormat;
30
+ songName?: string;
31
  sourceKind: SourceKind;
32
  sourceUrl?: string;
33
  resolvedUrl?: string;
 
38
  filename: string;
39
  originalUrl: string;
40
  outputFormat: OutputFormat;
41
+ songName?: string;
42
  sourceKind: SourceKind;
43
  sourceUrl?: string;
44
  resolvedUrl?: string;
 
52
  filename: string;
53
  originalUrl: string;
54
  outputFormat: OutputFormat;
55
+ songName?: string;
56
  sourceKind: SourceKind;
57
  sourceUrl?: string;
58
  resolvedUrl?: string;
 
76
  filename: string;
77
  originalUrl: string;
78
  outputFormat: OutputFormat;
79
+ songName?: string;
80
  sourceKind: SourceKind;
81
  sourceUrl?: string;
82
  resolvedUrl?: string;