Spaces:
Sleeping
Sleeping
| /** | |
| * Audio Processing API Client | |
| * Handles communication with the FastAPI backend | |
| */ | |
| const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000"; | |
| export interface StemSeparationResult { | |
| status: string; | |
| model: string; | |
| format: string; | |
| stems: Record<string, { | |
| filename: string; | |
| path: string; | |
| size: number; | |
| }>; | |
| } | |
| export interface MIDIExtractionResult { | |
| status: string; | |
| method: string; | |
| midi_file: { | |
| filename: string; | |
| path: string; | |
| size: number; | |
| }; | |
| parameters?: Record<string, number>; | |
| note?: string; | |
| } | |
| export interface AudioAnalysisResult { | |
| status: string; | |
| filename: string; | |
| file_size: number; | |
| analysis_type: string; | |
| metadata?: { | |
| duration?: number; | |
| sample_rate?: number; | |
| channels?: number; | |
| format?: string; | |
| subtype?: string; | |
| }; | |
| tempo?: { | |
| bpm: number; | |
| confidence: number; | |
| }; | |
| key?: { | |
| key: string; | |
| confidence: number; | |
| }; | |
| chords?: any[]; | |
| } | |
| export interface AgenticWorkflowResult { | |
| workflow: string; | |
| original_file: string; | |
| steps: string[]; | |
| analysis?: AudioAnalysisResult; | |
| stems?: StemSeparationResult; | |
| midi?: MIDIExtractionResult; | |
| } | |
| export class AudioProcessingAPI { | |
| private baseUrl: string; | |
| constructor(baseUrl: string = API_BASE_URL) { | |
| this.baseUrl = baseUrl; | |
| } | |
| /** | |
| * Separate audio into stems | |
| */ | |
| async separateStems( | |
| file: File, | |
| options: { | |
| model?: string; | |
| stems?: string[]; | |
| format?: string; | |
| } = {} | |
| ): Promise<StemSeparationResult> { | |
| const formData = new FormData(); | |
| formData.append("file", file); | |
| if (options.model) formData.append("model", options.model); | |
| if (options.stems) { | |
| options.stems.forEach(stem => formData.append("stems", stem)); | |
| } | |
| if (options.format) formData.append("format", options.format); | |
| const response = await fetch(`${this.baseUrl}/api/process/stem-separation`, { | |
| method: "POST", | |
| body: formData, | |
| }); | |
| if (!response.ok) { | |
| const error = await response.json(); | |
| throw new Error(error.detail || "Stem separation failed"); | |
| } | |
| return response.json(); | |
| } | |
| /** | |
| * Extract MIDI from audio | |
| */ | |
| async extractMIDI( | |
| file: File, | |
| options: { | |
| method?: string; | |
| threshold?: number; | |
| min_note_duration?: number; | |
| } = {} | |
| ): Promise<MIDIExtractionResult> { | |
| const formData = new FormData(); | |
| formData.append("file", file); | |
| if (options.method) formData.append("method", options.method); | |
| if (options.threshold !== undefined) { | |
| formData.append("threshold", options.threshold.toString()); | |
| } | |
| if (options.min_note_duration !== undefined) { | |
| formData.append("min_note_duration", options.min_note_duration.toString()); | |
| } | |
| const response = await fetch(`${this.baseUrl}/api/process/midi-extraction`, { | |
| method: "POST", | |
| body: formData, | |
| }); | |
| if (!response.ok) { | |
| const error = await response.json(); | |
| throw new Error(error.detail || "MIDI extraction failed"); | |
| } | |
| return response.json(); | |
| } | |
| /** | |
| * Analyze audio file | |
| */ | |
| async analyzeAudio( | |
| file: File, | |
| analysisType: string = "full" | |
| ): Promise<AudioAnalysisResult> { | |
| const formData = new FormData(); | |
| formData.append("file", file); | |
| formData.append("analysis_type", analysisType); | |
| const response = await fetch(`${this.baseUrl}/api/process/analyze`, { | |
| method: "POST", | |
| body: formData, | |
| }); | |
| if (!response.ok) { | |
| const error = await response.json(); | |
| throw new Error(error.detail || "Audio analysis failed"); | |
| } | |
| return response.json(); | |
| } | |
| /** | |
| * Run complete agentic workflow | |
| */ | |
| async runAgenticWorkflow( | |
| file: File, | |
| workflow: string = "full-production", | |
| options?: Record<string, any> | |
| ): Promise<AgenticWorkflowResult> { | |
| const formData = new FormData(); | |
| formData.append("file", file); | |
| formData.append("workflow", workflow); | |
| if (options) { | |
| formData.append("options", JSON.stringify(options)); | |
| } | |
| const response = await fetch(`${this.baseUrl}/api/process/agentic-workflow`, { | |
| method: "POST", | |
| body: formData, | |
| }); | |
| if (!response.ok) { | |
| const error = await response.json(); | |
| throw new Error(error.detail || "Workflow execution failed"); | |
| } | |
| return response.json(); | |
| } | |
| /** | |
| * Get file from server | |
| */ | |
| getFileUrl(path: string): string { | |
| return `${this.baseUrl}/api/files/${path}`; | |
| } | |
| /** | |
| * Download file as blob | |
| */ | |
| async downloadFile(path: string): Promise<Blob> { | |
| const response = await fetch(`${this.baseUrl}/api/files/${path}`); | |
| if (!response.ok) { | |
| throw new Error("File download failed"); | |
| } | |
| return response.blob(); | |
| } | |
| /** | |
| * Delete file from server | |
| */ | |
| async deleteFile(path: string): Promise<void> { | |
| const response = await fetch(`${this.baseUrl}/api/files/${path}`, { | |
| method: "DELETE", | |
| }); | |
| if (!response.ok) { | |
| throw new Error("File deletion failed"); | |
| } | |
| } | |
| /** | |
| * Health check | |
| */ | |
| async healthCheck(): Promise<{ status: string }> { | |
| const response = await fetch(`${this.baseUrl}/health`); | |
| if (!response.ok) { | |
| throw new Error("API health check failed"); | |
| } | |
| return response.json(); | |
| } | |
| } | |
| export const audioProcessingAPI = new AudioProcessingAPI(); | |