Compare commits
14 Commits
dc2f85734f
...
556c200283
| Author | SHA1 | Date | |
|---|---|---|---|
| 556c200283 | |||
| 2d9297d9a3 | |||
| 70818ca117 | |||
| 1b097b617d | |||
| 5d89962ed6 | |||
| fb06fb805d | |||
| 894a7d478b | |||
| 505f2b7055 | |||
| 85bb67078c | |||
| 7d28d28ee4 | |||
| f44e44b68b | |||
| 14a9f16b04 | |||
| 5a76fd4708 | |||
| 328bb25cf2 |
@@ -0,0 +1,5 @@
|
||||
node_modules
|
||||
.git
|
||||
dist
|
||||
*.env
|
||||
|
||||
@@ -4,7 +4,7 @@ An evolving **audio processing pipeline** designed to separate and enhance audio
|
||||
|
||||
---
|
||||
|
||||
🚀 Current Features
|
||||
**Current Features**
|
||||
|
||||
- **Audio Input Handling**: Uses librosa for reading and handling audio files.
|
||||
- **Preprocessing**: Includes resampling, normalization, and trimming using librosa.
|
||||
@@ -15,7 +15,7 @@ An evolving **audio processing pipeline** designed to separate and enhance audio
|
||||
- **Modular Architecture**: Designed for easy extension and customization.
|
||||
|
||||
---
|
||||
📁 Project Structure
|
||||
**Project Structure**
|
||||
|
||||
```bash
|
||||
freqsplit/
|
||||
@@ -39,10 +39,10 @@ freqsplit/
|
||||
└── venv/ # Virtual environment (should be excluded from version control)
|
||||
```
|
||||
|
||||
### 📝 Wiki
|
||||
### Wiki
|
||||
|
||||
For detailed instructions on installing dependencies, setting up Python environments, and configuring the project, visit the [Wiki](https://github.com/joelmathewthomas/freq-split-enhance/wiki).
|
||||
|
||||
## 🛡️ License
|
||||
## License
|
||||
|
||||
This project is licensed under the Apache License 2.0.
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# ---------------------
|
||||
# Stage 1: Builder
|
||||
# ---------------------
|
||||
FROM python:3.12.7 AS builder
|
||||
|
||||
# Install build deps
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential libpq-dev git curl \
|
||||
libffi-dev libssl-dev rustc cargo \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
COPY src/ src/
|
||||
|
||||
# Copy metadata and install deps
|
||||
COPY pyproject.toml requirements.txt ./
|
||||
RUN pip install --upgrade pip && \
|
||||
pip install --prefix=/install --no-cache-dir -e .
|
||||
|
||||
# --- Patch Demucs bug here ---
|
||||
# Fixes the following error when using htdemucs model:
|
||||
# RuntimeError: unsupported operation: more than one element of the written-to tensor refers to a single memory location. Please clone() the tensor before performing the operation.
|
||||
RUN find /install -type f -path "*/site-packages/demucs/separate.py" \
|
||||
-exec sed -i 's/wav -= ref.mean()/wav = (wav - ref.mean()).clone()/' {} \;
|
||||
|
||||
|
||||
|
||||
# Copy source for build-time extras (if needed)
|
||||
COPY api/ api/
|
||||
COPY docker/daphne api/
|
||||
COPY docker/celery api/
|
||||
COPY docker/wrapper api/
|
||||
|
||||
# ---------------------
|
||||
# Stage 2: Runtime
|
||||
# ---------------------
|
||||
FROM python:3.12.7
|
||||
# Install runtime system packages (only what’s needed)
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libpq-dev curl libffi-dev libssl-dev wget\
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy only installed site-packages and app
|
||||
COPY --from=builder /install /usr/local
|
||||
COPY api/ api/
|
||||
COPY src/ src/
|
||||
COPY pytest.ini .
|
||||
COPY tests/ tests/
|
||||
COPY LICENSE .
|
||||
COPY docker/daphne api/
|
||||
COPY docker/celery api/
|
||||
COPY docker/wrapper api/
|
||||
|
||||
# Test packages and download model checkpoints
|
||||
RUN pytest
|
||||
RUN rm pytest.ini
|
||||
RUN rm -rf tests/
|
||||
|
||||
|
||||
# Set working dir for backend
|
||||
WORKDIR /app/api
|
||||
|
||||
ENV CELERY_BROKER_URL=redis://redis:6379/0
|
||||
|
||||
EXPOSE 8000
|
||||
CMD ./wrapper
|
||||
@@ -1,3 +1,5 @@
|
||||
import os
|
||||
|
||||
"""
|
||||
Django settings for backend project.
|
||||
|
||||
@@ -141,7 +143,7 @@ STATIC_URL = 'static/'
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
# COnfigure Redis as message broker
|
||||
CELERY_BROKER_URL = 'redis://localhost:6379/0'
|
||||
CELERY_BROKER_URL = os.getenv('CELERY_BROKER_URL', 'redis://localhost:6379/0')
|
||||
CELERY_ACCEPT_CONTENT = ['json']
|
||||
CELERY_TASK_SERIALIZER = 'json'
|
||||
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
VITE_API_BASE_URL=http://localhost:8000
|
||||
VITE_WS_BASE_URL=ws://localhost:8000
|
||||
@@ -0,0 +1,2 @@
|
||||
VITE_API_BASE_URL=http://backend:8000
|
||||
VITE_WS_BASE_URL=ws://backend:8000
|
||||
@@ -35,7 +35,6 @@ Thumbs.db
|
||||
.vite/
|
||||
|
||||
### Environment Variables ###
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
FROM node:20 AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy and install dependencies
|
||||
COPY client/package.json client/package-lock.json* ./
|
||||
RUN npm install
|
||||
|
||||
# Copy the source code
|
||||
COPY client/ .
|
||||
|
||||
# Build the app using docker mode env
|
||||
ENV NODE_ENV=production
|
||||
RUN npm run build -- --mode docker
|
||||
|
||||
# Stage 2: Serve with nginx
|
||||
FROM nginx:stable-alpine AS production
|
||||
|
||||
# Copy built frontend from builder stage
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
@@ -1,25 +1,31 @@
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
Typography,
|
||||
Container,
|
||||
Button,
|
||||
Paper,
|
||||
Box,
|
||||
Card,
|
||||
CardContent,
|
||||
Grid,
|
||||
useTheme
|
||||
import {
|
||||
Typography,
|
||||
Container,
|
||||
Button,
|
||||
Paper,
|
||||
Box,
|
||||
Card,
|
||||
CardContent,
|
||||
Grid,
|
||||
useTheme,
|
||||
Slide,
|
||||
Zoom,
|
||||
} from '@mui/material';
|
||||
import {
|
||||
CloudUpload as CloudUploadIcon,
|
||||
import {
|
||||
CloudUpload as CloudUploadIcon,
|
||||
PlayArrow as PlayArrowIcon,
|
||||
Check as CheckIcon
|
||||
Check as CheckIcon,
|
||||
GraphicEq as GraphicEqIcon,
|
||||
NoiseAware as NoiseAwareIcon,
|
||||
MusicNote as MusicNoteIcon,
|
||||
} from '@mui/icons-material';
|
||||
|
||||
function LandingPage() {
|
||||
const navigate = useNavigate();
|
||||
const theme = useTheme();
|
||||
|
||||
const showContent = true;
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -33,73 +39,163 @@ function LandingPage() {
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="md">
|
||||
<Paper
|
||||
elevation={3}
|
||||
sx={{
|
||||
padding: theme.spacing(6),
|
||||
textAlign: 'center',
|
||||
background: 'rgba(255, 255, 255, 0.9)',
|
||||
}}
|
||||
>
|
||||
<Typography variant="h3" gutterBottom color="primary">
|
||||
Welcome to FreqSplit
|
||||
</Typography>
|
||||
<Typography variant="h5" paragraph color="textSecondary">
|
||||
Upload, preview, and process your audio files with ease
|
||||
</Typography>
|
||||
<Box sx={{ mt: 4 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
size="large"
|
||||
startIcon={<CloudUploadIcon />}
|
||||
onClick={() => navigate('/upload')}
|
||||
sx={{ mr: 2 }}
|
||||
>
|
||||
Get Started
|
||||
</Button>
|
||||
</Box>
|
||||
</Paper>
|
||||
|
||||
<Grid container spacing={4} sx={{ mt: 4 }}>
|
||||
<Slide direction="down" in={showContent} mountOnEnter unmountOnExit>
|
||||
<Paper
|
||||
elevation={3}
|
||||
sx={{
|
||||
padding: theme.spacing(6),
|
||||
textAlign: 'center',
|
||||
background: 'rgba(255, 255, 255, 0.9)',
|
||||
}}
|
||||
>
|
||||
<Typography variant="h3" gutterBottom color="primary">
|
||||
Welcome to FreqSplit
|
||||
</Typography>
|
||||
<Typography variant="h5" paragraph color="textSecondary">
|
||||
Upload, preview, and process your audio files with ease
|
||||
</Typography>
|
||||
<Box sx={{ mt: 4 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
size="large"
|
||||
startIcon={<CloudUploadIcon />}
|
||||
onClick={() => navigate('/upload')}
|
||||
sx={{ mr: 2 }}
|
||||
>
|
||||
Get Started
|
||||
</Button>
|
||||
</Box>
|
||||
</Paper>
|
||||
</Slide>
|
||||
|
||||
<Grid container spacing={4} sx={{ mt: 4, justifyContent: 'center' }}>
|
||||
<Grid item xs={12} md={4}>
|
||||
<Card sx={{ height: '100%' }}>
|
||||
<CardContent sx={{ textAlign: 'center' }}>
|
||||
<CloudUploadIcon color="primary" sx={{ fontSize: 60, mb: 2 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Easy Upload
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Drag and drop your media files for quick processing
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Zoom in={showContent} style={{ transitionDelay: '100ms' }}>
|
||||
<Card
|
||||
sx={{
|
||||
height: '100%',
|
||||
transition: 'transform 0.3s ease-in-out',
|
||||
'&:hover': { transform: 'scale(1.05)' },
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center' }}>
|
||||
<CloudUploadIcon color="primary" sx={{ fontSize: 60, mb: 2 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Upload or Record
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Drag and drop your media files or record directly for quick processing.
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Zoom>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={4}>
|
||||
<Card sx={{ height: '100%' }}>
|
||||
<CardContent sx={{ textAlign: 'center' }}>
|
||||
<PlayArrowIcon color="primary" sx={{ fontSize: 60, mb: 2 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Preview Media
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Review your files before processing
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Zoom in={showContent} style={{ transitionDelay: '200ms' }}>
|
||||
<Card
|
||||
sx={{
|
||||
height: '100%',
|
||||
transition: 'transform 0.3s ease-in-out',
|
||||
'&:hover': { transform: 'scale(1.05)' },
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center' }}>
|
||||
<PlayArrowIcon color="primary" sx={{ fontSize: 60, mb: 2 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Preview Media
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Review your files before processing.
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Zoom>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={4}>
|
||||
<Card sx={{ height: '100%' }}>
|
||||
<CardContent sx={{ textAlign: 'center' }}>
|
||||
<CheckIcon color="primary" sx={{ fontSize: 60, mb: 2 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
View Results
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Download and share your processed media
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Zoom in={showContent} style={{ transitionDelay: '300ms' }}>
|
||||
<Card
|
||||
sx={{
|
||||
height: '100%',
|
||||
transition: 'transform 0.3s ease-in-out',
|
||||
'&:hover': { transform: 'scale(1.05)' },
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center' }}>
|
||||
<CheckIcon color="primary" sx={{ fontSize: 60, mb: 2 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
View Results
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Download and share your processed media.
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Zoom>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12} md={4}>
|
||||
<Zoom in={showContent} style={{ transitionDelay: '400ms' }}>
|
||||
<Card
|
||||
sx={{
|
||||
height: '100%',
|
||||
transition: 'transform 0.3s ease-in-out',
|
||||
'&:hover': { transform: 'scale(1.05)' },
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center' }}>
|
||||
<GraphicEqIcon color="primary" sx={{ fontSize: 60, mb: 2 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Audio Source Separation (Demucs)
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Separate audio sources with state-of-the-art Demucs.
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Zoom>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={4}>
|
||||
<Zoom in={showContent} style={{ transitionDelay: '500ms' }}>
|
||||
<Card
|
||||
sx={{
|
||||
height: '100%',
|
||||
transition: 'transform 0.3s ease-in-out',
|
||||
'&:hover': { transform: 'scale(1.05)' },
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center' }}>
|
||||
<NoiseAwareIcon color="primary" sx={{ fontSize: 60, mb: 2 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Noise Reduction (DeepFilterNet)
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Reduce noise effectively using DeepFilterNet.
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Zoom>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={4}>
|
||||
<Zoom in={showContent} style={{ transitionDelay: '600ms' }}>
|
||||
<Card
|
||||
sx={{
|
||||
height: '100%',
|
||||
transition: 'transform 0.3s ease-in-out',
|
||||
'&:hover': { transform: 'scale(1.05)' },
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center' }}>
|
||||
<MusicNoteIcon color="primary" sx={{ fontSize: 60, mb: 2 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Audio Processing (Librosa)
|
||||
</Typography>
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
Advanced audio processing and manipulation with Librosa.
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Zoom>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Container>
|
||||
|
||||
+101
-34
@@ -13,7 +13,8 @@ import {
|
||||
} from "@mui/material";
|
||||
import {
|
||||
CloudUpload as CloudUploadIcon,
|
||||
VolumeUp as VolumeUpIcon,
|
||||
Mic as MicIcon,
|
||||
Stop as StopIcon
|
||||
} from "@mui/icons-material";
|
||||
import StepperComponent from "../components/StepperComponent";
|
||||
import { useWebSocket } from "../contexts/WebSocketContext";
|
||||
@@ -29,6 +30,48 @@ function UploadPage() {
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [upload, setUpload] = useState(false);
|
||||
const [inputEnabled, setInputEnabled] = useState(false);
|
||||
const [isRecording, setIsRecording] = useState(false);
|
||||
const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null);
|
||||
|
||||
const startRecording = async () => {
|
||||
setUpload(false);
|
||||
setResponse({
|
||||
audio_class: "",
|
||||
file_uuid: "",
|
||||
sr: 0,
|
||||
spectrogram: "",
|
||||
spec_sr: 0
|
||||
});
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
const recorder = new MediaRecorder(stream);
|
||||
setMediaRecorder(recorder);
|
||||
|
||||
const chunks: Blob[] = [];
|
||||
recorder.ondataavailable = (e) => chunks.push(e.data);
|
||||
recorder.onstop = () => {
|
||||
const blob = new Blob(chunks, { type: "audio/wav" });
|
||||
const file = new File([blob], "recording.wav", { type: "audio/wav" });
|
||||
const tracks = stream.getTracks();
|
||||
tracks.forEach(track => track.stop());
|
||||
validateAndSetFile(file);
|
||||
handleUpload(file);
|
||||
};
|
||||
|
||||
recorder.start();
|
||||
setIsRecording(true);
|
||||
} catch (error) {
|
||||
console.error("Failed to start recording:", error);
|
||||
showErrorToast("Failed to start recording");
|
||||
}
|
||||
};
|
||||
|
||||
const stopRecording = () => {
|
||||
if (mediaRecorder) {
|
||||
mediaRecorder.stop();
|
||||
setIsRecording(false);
|
||||
}
|
||||
};
|
||||
|
||||
const showErrorToast = (message: string) => {
|
||||
setToastMessage(message);
|
||||
@@ -220,8 +263,52 @@ function UploadPage() {
|
||||
|
||||
<Paper elevation={3} sx={{ p: 4, mt: 4, textAlign: "center" }}>
|
||||
<Typography variant="h4" gutterBottom color="primary">
|
||||
Upload Your Media
|
||||
Upload or Record Your Media
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
border: `2px dashed ${
|
||||
isDragging ? theme.palette.primary.main : theme.palette.divider
|
||||
}`,
|
||||
borderRadius: 2,
|
||||
p: 6,
|
||||
mt: 3,
|
||||
mb: 3,
|
||||
backgroundColor: isDragging
|
||||
? "rgba(63, 81, 181, 0.08)"
|
||||
: "transparent",
|
||||
transition: "all 0.3s ease",
|
||||
cursor: "pointer",
|
||||
overflow: "auto",
|
||||
}}
|
||||
onDragOver={handleDragOver}
|
||||
onDragLeave={handleDragLeave}
|
||||
onDrop={handleDrop}
|
||||
onClick={() => document.getElementById("fileInput")?.click()}
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
id="fileInput"
|
||||
style={{ display: "none" }}
|
||||
onChange={handleFileChange}
|
||||
accept="audio/*"
|
||||
disabled={!inputEnabled}
|
||||
/>
|
||||
<CloudUploadIcon color="primary" sx={{ fontSize: 64, mb: 2 }} />
|
||||
<Typography
|
||||
variant="h6"
|
||||
gutterBottom
|
||||
sx={{
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
{file ? file.name : "Drop your file here or click to browse files"}
|
||||
</Typography>
|
||||
<Typography>Supported formats: MP3, WAV, AAC, OGG</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
@@ -244,39 +331,19 @@ function UploadPage() {
|
||||
onDrop={handleDrop}
|
||||
onClick={() => document.getElementById("fileInput")?.click()}
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
id="fileInput"
|
||||
style={{ display: "none" }}
|
||||
onChange={handleFileChange}
|
||||
accept="audio/*"
|
||||
disabled={!inputEnabled}
|
||||
/>
|
||||
|
||||
<CloudUploadIcon color="primary" sx={{ fontSize: 64, mb: 2 }} />
|
||||
<Typography
|
||||
variant="h6"
|
||||
gutterBottom
|
||||
sx={{
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
maxWidth: "100%", // Ensure it adapts to the box size
|
||||
}}
|
||||
>
|
||||
{file ? file.name : "Drop your file here or click to browse files"}
|
||||
</Typography>
|
||||
<Typography>
|
||||
Max file size: 100MB
|
||||
</Typography>
|
||||
{file && (
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
{file.type.includes("audio") ? <VolumeUpIcon sx={{ mr: 1 }} /> : null}
|
||||
{file.type} - {(file.size / (1024 * 1024)).toFixed(2)} MB
|
||||
</Typography>
|
||||
)}
|
||||
<Button
|
||||
variant="contained"
|
||||
color={isRecording ? "secondary" : "primary"}
|
||||
startIcon={isRecording ? <StopIcon /> : <MicIcon />}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation(); // Prevent click from reaching file input
|
||||
isRecording ? stopRecording() : startRecording();
|
||||
}}
|
||||
disabled={!isConnected}
|
||||
>
|
||||
{isRecording ? "Stop Recording" : "Start Recording"}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ mt: 4, display: "flex", justifyContent: "space-between" }}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
|
||||
+20
-15
@@ -1,20 +1,25 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:8000',
|
||||
changeOrigin: true,
|
||||
export default defineConfig(({ mode }) => {
|
||||
// Load env file based on mode (e.g. development, production, docker)
|
||||
const env = loadEnv(mode, process.cwd())
|
||||
|
||||
return {
|
||||
plugins: [react()],
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: env.VITE_API_BASE_URL,
|
||||
changeOrigin: true,
|
||||
},
|
||||
'/ws': {
|
||||
target: env.VITE_WS_BASE_URL,
|
||||
ws: true,
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
'/ws': {
|
||||
target: "ws://localhost:8000",
|
||||
ws: true,
|
||||
changeOrigin: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: api/Dockerfile
|
||||
image: joelmathewthomas/freqsplit-api:latest
|
||||
container_name: freqsplit-api
|
||||
depends_on:
|
||||
- redis
|
||||
networks:
|
||||
- freqnet
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: 1
|
||||
capabilities: [gpu]
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8000/api/ping"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 24
|
||||
|
||||
redis:
|
||||
image: redis:7
|
||||
container_name: freqsplit-redis
|
||||
networks:
|
||||
- freqnet
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: client/Dockerfile
|
||||
image: joelmathewthomas/freqsplit-client:latest
|
||||
container_name: freqsplit-client
|
||||
ports:
|
||||
- "80:80"
|
||||
networks:
|
||||
- freqnet
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
freqnet:
|
||||
driver: bridge
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: api/Dockerfile
|
||||
image: joelmathewthomas/freqsplit-api:latest
|
||||
container_name: freqsplit-api
|
||||
depends_on:
|
||||
- redis
|
||||
networks:
|
||||
- freqnet
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8000/api/ping"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 24
|
||||
|
||||
redis:
|
||||
image: redis:7
|
||||
container_name: freqsplit-redis
|
||||
networks:
|
||||
- freqnet
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: client/Dockerfile
|
||||
image: joelmathewthomas/freqsplit-client:latest
|
||||
container_name: freqsplit-client
|
||||
ports:
|
||||
- "80:80"
|
||||
networks:
|
||||
- freqnet
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
freqnet:
|
||||
driver: bridge
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
backend:
|
||||
image: ghcr.io/joelmathewthomas/freqsplit-api:latest
|
||||
build: null
|
||||
|
||||
frontend:
|
||||
image: ghcr.io/joelmathewthomas/freqsplit-client:latest
|
||||
build: null
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
backend:
|
||||
image: ghcr.io/joelmathewthomas/freqsplit-api:latest
|
||||
build: null
|
||||
|
||||
frontend:
|
||||
image: ghcr.io/joelmathewthomas/freqsplit-client:latest
|
||||
build: null
|
||||
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
celery -A backend worker --loglevel=info
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
daphne -b 0.0.0.0 -p 8000 --proxy-headers backend.asgi:application
|
||||
@@ -0,0 +1,28 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 100M;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_read_timeout 300;
|
||||
proxy_connect_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
}
|
||||
|
||||
location /ws/ {
|
||||
proxy_pass http://backend:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Start the first process
|
||||
./celery &
|
||||
|
||||
# Start the second process
|
||||
./daphne &
|
||||
|
||||
# Wait for any process to exit
|
||||
wait -n
|
||||
|
||||
# Exit with status of process that exited first
|
||||
exit $?
|
||||
+152
-151
@@ -6,157 +6,158 @@ build-backend = "setuptools.build_meta"
|
||||
name = "freqsplit"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aiohappyeyeballs" = "2.4.6",
|
||||
"aiohttp" = "3.11.13",
|
||||
"aiosignal" = "1.3.2",
|
||||
"amqp" = "5.3.1",
|
||||
"antlr4-python3-runtime" = "4.9.3",
|
||||
"appdirs" = "1.4.4",
|
||||
"asgiref" = "3.8.1",
|
||||
"asteroid" = "0.7.0",
|
||||
"asteroid-filterbanks" = "0.4.0",
|
||||
"attrs" = "25.1.0",
|
||||
"audioread" = "3.0.1",
|
||||
"autobahn" = "24.4.2",
|
||||
"Automat" = "24.8.1",
|
||||
"billiard" = "4.2.1",
|
||||
"cached-property" = "2.0.1",
|
||||
"celery" = "5.4.0",
|
||||
"certifi" = "2025.1.31",
|
||||
"cffi" = "1.17.1",
|
||||
"channels" = "4.2.0",
|
||||
"charset-normalizer" = "3.4.1",
|
||||
"click" = "8.1.8",
|
||||
"click-didyoumean" = "0.3.1",
|
||||
"click-plugins" = "1.1.1",
|
||||
"click-repl" = "0.3.0",
|
||||
"cloudpickle" = "3.1.1",
|
||||
"colorama" = "0.4.6",
|
||||
"constantly" = "23.10.4",
|
||||
"contourpy" = "1.3.1",
|
||||
"cors" = "1.0.1",
|
||||
"cryptography" = "44.0.2",
|
||||
"cycler" = "0.12.1",
|
||||
"daphne" = "4.1.2",
|
||||
"decorator" = "5.2.1",
|
||||
"DeepFilterLib" = "0.5.6",
|
||||
"DeepFilterNet" = "0.5.6",
|
||||
"demucs" = "4.0.1",
|
||||
"Django" = "5.1.6",
|
||||
"django-cors-headers" = "4.7.0",
|
||||
"djangorestframework" = "3.15.2",
|
||||
"dora_search" = "0.1.12",
|
||||
"einops" = "0.8.1",
|
||||
"filelock" = "3.17.0",
|
||||
"fonttools" = "4.56.0",
|
||||
"frozenlist" = "1.5.0",
|
||||
"fsspec" = "2025.2.0",
|
||||
"future" = "1.0.0",
|
||||
"gevent" = "24.11.1",
|
||||
"greenlet" = "3.1.1",
|
||||
"huggingface-hub" = "0.29.1",
|
||||
"hyperlink" = "21.0.0",
|
||||
"idna" = "3.10",
|
||||
"incremental" = "24.7.2",
|
||||
"iniconfig" = "2.0.0",
|
||||
"Jinja2" = "3.1.5",
|
||||
"joblib" = "1.4.2",
|
||||
"julius" = "0.2.7",
|
||||
"kiwisolver" = "1.4.8",
|
||||
"kombu" = "5.4.2",
|
||||
"lameenc" = "1.8.1",
|
||||
"lazy_loader" = "0.4",
|
||||
"librosa" = "0.10.2.post1",
|
||||
"lightning-utilities" = "0.12.0",
|
||||
"llvmlite" = "0.44.0",
|
||||
"loguru" = "0.7.3",
|
||||
"MarkupSafe" = "3.0.2",
|
||||
"matplotlib" = "3.10.0",
|
||||
"mir_eval" = "0.8.2",
|
||||
"mpmath" = "1.3.0",
|
||||
"msgpack" = "1.1.0",
|
||||
"multidict" = "6.1.0",
|
||||
"networkx" = "3.4.2",
|
||||
"numba" = "0.61.0",
|
||||
"numpy" = "1.26.4",
|
||||
"nvidia-cublas-cu12" = "12.4.5.8",
|
||||
"nvidia-cuda-cupti-cu12" = "12.4.127",
|
||||
"nvidia-cuda-nvrtc-cu12" = "12.4.127",
|
||||
"nvidia-cuda-runtime-cu12" = "12.4.127",
|
||||
"nvidia-cudnn-cu12" = "9.1.0.70",
|
||||
"nvidia-cufft-cu12" = "11.2.1.3",
|
||||
"nvidia-curand-cu12" = "10.3.5.147",
|
||||
"nvidia-cusolver-cu12" = "11.6.1.9",
|
||||
"nvidia-cusparse-cu12" = "12.3.1.170",
|
||||
"nvidia-cusparselt-cu12" = "0.6.2",
|
||||
"nvidia-nccl-cu12" = "2.21.5",
|
||||
"nvidia-nvjitlink-cu12" = "12.4.127",
|
||||
"nvidia-nvtx-cu12" = "12.4.127",
|
||||
"omegaconf" = "2.3.0",
|
||||
"openunmix" = "1.3.0",
|
||||
"packaging" = "23.2",
|
||||
"pandas" = "2.2.3",
|
||||
"panns-inference" = "0.1.1",
|
||||
"pb-bss-eval" = "0.0.2",
|
||||
"pesq" = "0.0.4",
|
||||
"pillow" = "11.1.0",
|
||||
"platformdirs" = "4.3.6",
|
||||
"pluggy" = "1.5.0",
|
||||
"pooch" = "1.8.2",
|
||||
"prompt_toolkit" = "3.0.50",
|
||||
"propcache" = "0.3.0",
|
||||
"pyasn1" = "0.6.1",
|
||||
"pyasn1_modules" = "0.4.1",
|
||||
"pycparser" = "2.22",
|
||||
"pyOpenSSL" = "25.0.0",
|
||||
"pyparsing" = "3.2.1",
|
||||
"PySocks" = "1.7.1",
|
||||
"pystoi" = "0.4.1",
|
||||
"pytest" = "8.3.4",
|
||||
"python-dateutil" = "2.9.0.post0",
|
||||
"pytorch-lightning" = "2.5.0.post0",
|
||||
"pytorch-ranger" = "0.1.1",
|
||||
"pytz" = "2025.1",
|
||||
"PyYAML" = "6.0.2",
|
||||
"redis" = "5.2.1",
|
||||
"regex" = "2024.11.6",
|
||||
"requests" = "2.32.3",
|
||||
"requests-file" = "2.1.0",
|
||||
"retrying" = "1.3.4",
|
||||
"safetensors" = "0.5.3",
|
||||
"scikit-learn" = "1.6.1",
|
||||
"scipy" = "1.15.2",
|
||||
"service-identity" = "24.2.0",
|
||||
"setuptools" = "75.8.1",
|
||||
"six" = "1.17.0",
|
||||
"soundfile" = "0.13.1",
|
||||
"soxr" = "0.5.0.post1",
|
||||
"sqlparse" = "0.5.3",
|
||||
"submitit" = "1.5.2",
|
||||
"sympy" = "1.13.1",
|
||||
"threadpoolctl" = "3.5.0",
|
||||
"tldextract" = "5.1.3",
|
||||
"tokenizers" = "0.21.0",
|
||||
"torch" = "2.6.0",
|
||||
"torch-optimizer" = "0.1.0",
|
||||
"torch-stoi" = "0.2.3",
|
||||
"torchaudio" = "2.6.0",
|
||||
"torchlibrosa" = "0.1.0",
|
||||
"torchmetrics" = "0.11.4",
|
||||
"tqdm" = "4.67.1",
|
||||
"transformers" = "4.49.0",
|
||||
"treetable" = "0.2.5",
|
||||
"triton" = "3.2.0",
|
||||
"Twisted" = "24.11.0",
|
||||
"txaio" = "23.1.1",
|
||||
"typing_extensions" = "4.12.2",
|
||||
"tzdata" = "2025.1",
|
||||
"urllib3" = "2.3.0",
|
||||
"vine" = "5.1.0",
|
||||
"wcwidth" = "0.2.13",
|
||||
"yarl" = "1.18.3",
|
||||
"zope.event" = "5.0",
|
||||
"zope.interface" = "7.2",
|
||||
"aiohappyeyeballs==2.4.6",
|
||||
"aiohttp==3.11.13",
|
||||
"aiosignal==1.3.2",
|
||||
"amqp==5.3.1",
|
||||
"antlr4-python3-runtime==4.9.3",
|
||||
"appdirs==1.4.4",
|
||||
"asgiref==3.8.1",
|
||||
"asteroid==0.7.0",
|
||||
"asteroid-filterbanks==0.4.0",
|
||||
"attrs==25.1.0",
|
||||
"audioread==3.0.1",
|
||||
"autobahn==24.4.2",
|
||||
"Automat==24.8.1",
|
||||
"billiard==4.2.1",
|
||||
"cached-property==2.0.1",
|
||||
"celery==5.4.0",
|
||||
"certifi==2025.1.31",
|
||||
"cffi==1.17.1",
|
||||
"channels==4.2.0",
|
||||
"channels_redis==4.2.1",
|
||||
"charset-normalizer==3.4.1",
|
||||
"click==8.1.8",
|
||||
"click-didyoumean==0.3.1",
|
||||
"click-plugins==1.1.1",
|
||||
"click-repl==0.3.0",
|
||||
"cloudpickle==3.1.1",
|
||||
"colorama==0.4.6",
|
||||
"constantly==23.10.4",
|
||||
"contourpy==1.3.1",
|
||||
"cors==1.0.1",
|
||||
"cryptography==44.0.2",
|
||||
"cycler==0.12.1",
|
||||
"daphne==4.1.2",
|
||||
"decorator==5.2.1",
|
||||
"DeepFilterLib==0.5.6",
|
||||
"DeepFilterNet==0.5.6",
|
||||
"demucs==4.0.1",
|
||||
"Django==5.1.6",
|
||||
"django-cors-headers==4.7.0",
|
||||
"djangorestframework==3.15.2",
|
||||
"dora_search==0.1.12",
|
||||
"einops==0.8.1",
|
||||
"filelock==3.17.0",
|
||||
"fonttools==4.56.0",
|
||||
"frozenlist==1.5.0",
|
||||
"fsspec==2025.2.0",
|
||||
"future==1.0.0",
|
||||
"gevent==24.11.1",
|
||||
"greenlet==3.1.1",
|
||||
"huggingface-hub==0.29.1",
|
||||
"hyperlink==21.0.0",
|
||||
"idna==3.10",
|
||||
"incremental==24.7.2",
|
||||
"iniconfig==2.0.0",
|
||||
"Jinja2==3.1.5",
|
||||
"joblib==1.4.2",
|
||||
"julius==0.2.7",
|
||||
"kiwisolver==1.4.8",
|
||||
"kombu==5.4.2",
|
||||
"lameenc==1.8.1",
|
||||
"lazy_loader==0.4",
|
||||
"librosa==0.10.2.post1",
|
||||
"lightning-utilities==0.12.0",
|
||||
"llvmlite==0.44.0",
|
||||
"loguru==0.7.3",
|
||||
"MarkupSafe==3.0.2",
|
||||
"matplotlib==3.10.0",
|
||||
"mir_eval==0.8.2",
|
||||
"mpmath==1.3.0",
|
||||
"msgpack==1.1.0",
|
||||
"multidict==6.1.0",
|
||||
"networkx==3.4.2",
|
||||
"numba==0.61.0",
|
||||
"numpy==1.26.4",
|
||||
"nvidia-cublas-cu12==12.4.5.8",
|
||||
"nvidia-cuda-cupti-cu12==12.4.127",
|
||||
"nvidia-cuda-nvrtc-cu12==12.4.127",
|
||||
"nvidia-cuda-runtime-cu12==12.4.127",
|
||||
"nvidia-cudnn-cu12==9.1.0.70",
|
||||
"nvidia-cufft-cu12==11.2.1.3",
|
||||
"nvidia-curand-cu12==10.3.5.147",
|
||||
"nvidia-cusolver-cu12==11.6.1.9",
|
||||
"nvidia-cusparse-cu12==12.3.1.170",
|
||||
"nvidia-cusparselt-cu12==0.6.2",
|
||||
"nvidia-nccl-cu12==2.21.5",
|
||||
"nvidia-nvjitlink-cu12==12.4.127",
|
||||
"nvidia-nvtx-cu12==12.4.127",
|
||||
"omegaconf==2.3.0",
|
||||
"openunmix==1.3.0",
|
||||
"packaging==23.2",
|
||||
"pandas==2.2.3",
|
||||
"panns-inference==0.1.1",
|
||||
"pb-bss-eval==0.0.2",
|
||||
"pesq==0.0.4",
|
||||
"pillow==11.1.0",
|
||||
"platformdirs==4.3.6",
|
||||
"pluggy==1.5.0",
|
||||
"pooch==1.8.2",
|
||||
"prompt_toolkit==3.0.50",
|
||||
"propcache==0.3.0",
|
||||
"pyasn1==0.6.1",
|
||||
"pyasn1_modules==0.4.1",
|
||||
"pycparser==2.22",
|
||||
"pyOpenSSL==25.0.0",
|
||||
"pyparsing==3.2.1",
|
||||
"PySocks==1.7.1",
|
||||
"pystoi==0.4.1",
|
||||
"pytest==8.3.4",
|
||||
"python-dateutil==2.9.0.post0",
|
||||
"pytorch-lightning==2.5.0.post0",
|
||||
"pytorch-ranger==0.1.1",
|
||||
"pytz==2025.1",
|
||||
"PyYAML==6.0.2",
|
||||
"redis==5.2.1",
|
||||
"regex==2024.11.6",
|
||||
"requests==2.32.3",
|
||||
"requests-file==2.1.0",
|
||||
"retrying==1.3.4",
|
||||
"safetensors==0.5.3",
|
||||
"scikit-learn==1.6.1",
|
||||
"scipy==1.15.2",
|
||||
"service-identity==24.2.0",
|
||||
"setuptools==75.8.1",
|
||||
"six==1.17.0",
|
||||
"soundfile==0.13.1",
|
||||
"soxr==0.5.0.post1",
|
||||
"sqlparse==0.5.3",
|
||||
"submitit==1.5.2",
|
||||
"sympy==1.13.1",
|
||||
"threadpoolctl==3.5.0",
|
||||
"tldextract==5.1.3",
|
||||
"tokenizers==0.21.0",
|
||||
"torch==2.6.0",
|
||||
"torch-optimizer==0.1.0",
|
||||
"torch-stoi==0.2.3",
|
||||
"torchaudio==2.6.0",
|
||||
"torchlibrosa==0.1.0",
|
||||
"torchmetrics==0.11.4",
|
||||
"tqdm==4.67.1",
|
||||
"transformers==4.49.0",
|
||||
"treetable==0.2.5",
|
||||
"triton==3.2.0",
|
||||
"Twisted==24.11.0",
|
||||
"txaio==23.1.1",
|
||||
"typing_extensions==4.12.2",
|
||||
"tzdata==2025.1",
|
||||
"urllib3==2.3.0",
|
||||
"vine==5.1.0",
|
||||
"wcwidth==0.2.13",
|
||||
"yarl==1.18.3",
|
||||
"zope.event==5.0",
|
||||
"zope.interface==7.2",
|
||||
]
|
||||
|
||||
[tool.setuptools]
|
||||
|
||||
@@ -17,6 +17,7 @@ celery==5.4.0
|
||||
certifi==2025.1.31
|
||||
cffi==1.17.1
|
||||
channels==4.2.0
|
||||
channels_redis==4.2.1
|
||||
charset-normalizer==3.4.1
|
||||
click==8.1.8
|
||||
click-didyoumean==0.3.1
|
||||
|
||||
Reference in New Issue
Block a user