imran056 commited on
Commit
ed11f41
Β·
verified Β·
1 Parent(s): 5c68745

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +52 -101
server.js CHANGED
@@ -29,87 +29,51 @@ const upload = multer({
29
  limits: { fileSize: 50 * 1024 * 1024 }
30
  });
31
 
32
- // 🎡 PROFESSIONAL AUDIO EFFECTS - PRODUCTION GRADE
33
  const EFFECTS = {
34
  lofi: {
35
- name: "LoFi Hip Hop (Professional)",
36
- description: "Deep breathing bass, vinyl warmth, tape saturation",
37
- command: `
38
- -af "asetrate=44100*0.92,atempo=1.087,lowpass=f=4200:p=1,highpass=f=85:p=1,bass=g=6:f=95:w=0.4,treble=g=-4:f=8000:w=0.6,equalizer=f=250:t=h:width=180:g=-2.5,equalizer=f=1000:t=h:width=500:g=1.5,equalizer=f=3500:t=h:width=1500:g=-1.8,equalizer=f=8000:t=h:width=2500:g=-4,acompressor=threshold=-22dB:ratio=3.5:attack=8:release=140:makeup=3,afftdn=nf=-28:tn=1,acrusher=bits=13:mix=0.28:mode=log:aa=0.5,vibrato=f=0.22:d=0.45,aphaser=in_gain=0.55:out_gain=0.85:delay=2.8:decay=0.45:speed=0.48,aecho=0.55:0.68:48:0.28,aecho=0.45:0.58:95:0.18,extrastereo=m=1.5,volume=1.15,alimiter=level_in=1:level_out=0.95:limit=0.98:attack=6:release=50"
39
- -ar 44100 -b:a 256k
40
- `
41
  },
42
 
43
  slowed_reverb: {
44
- name: "Slowed + Reverb (TikTok Style)",
45
- description: "Deep slow tempo, massive reverb, bass-heavy",
46
- command: `
47
- -af "atempo=0.82,asetrate=44100*0.93,lowpass=f=6000:p=1,highpass=f=70:p=1,bass=g=5:f=85:w=0.5,treble=g=-3:f=7000:w=0.7,equalizer=f=150:t=h:width=120:g=4,equalizer=f=3000:t=h:width=2000:g=-2,aecho=0.75:0.82:75:0.38,aecho=0.65:0.75:145:0.28,aecho=0.55:0.68:220:0.18,reverb=roomsize=0.92:damping=0.42:wetlevel=0.48:drylevel=0.52:width=1.0,chorus=0.6:0.85:52:0.38:0.22:2,acompressor=threshold=-18dB:ratio=2.8:attack=12:release=180:makeup=2,extrastereo=m=1.8,volume=1.25,alimiter=level_in=1:level_out=0.95:limit=0.98:attack=8:release=80"
48
- -ar 44100 -b:a 256k
49
- `
50
  },
51
 
52
  nightcore: {
53
- name: "Nightcore (High Energy)",
54
- description: "Fast tempo, bright highs, energetic feel",
55
- command: `
56
- -af "atempo=1.28,asetrate=44100*1.12,highpass=f=120:p=1,treble=g=5:f=6000:w=0.6,equalizer=f=1200:t=h:width=600:g=2.5,equalizer=f=4000:t=h:width=2000:g=3.5,equalizer=f=8000:t=h:width=3000:g=4,bass=g=-2:f=100:w=0.4,aexciter=level_in=1:level_out=1:amount=1.8:drive=4:blend=0.6:freq=7500:ceil=16000,acompressor=threshold=-16dB:ratio=3.2:attack=4:release=35:makeup=3,crystalizer=i=1.5:c=1,extrastereo=m=1.7,volume=1.28,alimiter=level_in=1:level_out=0.96:limit=0.99:attack=4:release=40"
57
- -ar 44100 -b:a 256k
58
- `
59
  },
60
 
61
  vaporwave: {
62
- name: "Vaporwave (Retro Aesthetic)",
63
- description: "Dreamy pitch, chorus layers, nostalgic vibe",
64
- command: `
65
- -af "asetrate=44100*0.87,atempo=1.15,lowpass=f=5500:p=1,highpass=f=90:p=1,equalizer=f=400:t=h:width=250:g=3.5,equalizer=f=2500:t=h:width=1500:g=-1.5,equalizer=f=6500:t=h:width=2000:g=-3,aphaser=in_gain=0.65:out_gain=0.82:delay=4.5:decay=0.55:speed=0.32,chorus=0.68:0.88:58:0.42:0.28:2,chorus=0.58:0.78:42:0.35:0.22:2,vibrato=f=0.18:d=0.5,reverb=roomsize=0.72:damping=0.38:wetlevel=0.38:drylevel=0.62:width=0.95,aecho=0.5:0.65:85:0.25,acompressor=threshold=-20dB:ratio=3:attack=10:release=100:makeup=2,extrastereo=m=1.6,volume=1.18,alimiter=level_in=1:level_out=0.94:limit=0.97:attack=7:release=60"
66
- -ar 44100 -b:a 256k
67
- `
68
  },
69
 
70
  "8d_audio": {
71
- name: "8D Audio (360Β° Immersive)",
72
- description: "Circular panning, spatial depth, headphone optimized",
73
- command: `
74
- -af "apulsator=hz=0.085:mode=sine:width=0.92,extrastereo=m=2.8:c=0,aecho=0.72:0.85:65:0.38,aecho=0.62:0.75:125:0.28,haas=level_in=1:level_out=1:side_gain=0.95:middle_source=mid:middle_phase=1,bass=g=3:f=90:w=0.45,reverb=roomsize=0.65:damping=0.5:wetlevel=0.32:drylevel=0.68:width=1.0,acompressor=threshold=-18dB:ratio=2.5:attack=8:release=90:makeup=2,volume=1.12,alimiter=level_in=1:level_out=0.95:limit=0.98:attack=5:release=50"
75
- -ar 44100 -b:a 256k
76
- `
77
  },
78
 
79
  bass_boosted: {
80
- name: "Bass Boosted (Sub Heavy)",
81
- description: "Maximum sub-bass, club-style punch",
82
- command: `
83
- -af "bass=g=18:f=95:w=0.35,bass=g=12:f=65:w=0.25,equalizer=f=45:t=h:width=35:g=10,equalizer=f=100:t=h:width=80:g=9,equalizer=f=250:t=h:width=150:g=6,equalizer=f=800:t=h:width=400:g=-2,equalizer=f=4000:t=h:width=2000:g=-4,acompressor=threshold=-24dB:ratio=6:attack=4:release=45:makeup=5,asubboost=dry=0.7:wet=0.3:decay=0.7:feedback=0.6:cutoff=150:slope=1,extrastereo=m=1.4,volume=1.15,alimiter=level_in=1.1:level_out=0.96:limit=0.99:attack=3:release=30:asc=1"
84
- -ar 44100 -b:a 256k
85
- `
86
  },
87
 
88
  ambient: {
89
- name: "Ambient Chill (Atmospheric)",
90
- description: "Ethereal space, long reverb, dreamy texture",
91
- command: `
92
- -af "asetrate=44100*0.96,atempo=1.042,lowpass=f=7000:p=1,highpass=f=60:p=1,equalizer=f=2000:t=h:width=1500:g=-2.5,equalizer=f=6000:t=h:width=3000:g=-4.5,reverb=roomsize=0.95:damping=0.28:wetlevel=0.55:drylevel=0.45:width=1.0,chorus=0.65:0.88:48:0.42:0.25:3,aecho=0.6:0.75:150:0.32,aecho=0.5:0.65:280:0.22,aecho=0.4:0.55:420:0.15,aphaser=in_gain=0.45:out_gain=0.72:delay=3.8:decay=0.48:speed=0.38,acompressor=threshold=-20dB:ratio=2.2:attack=15:release=200:makeup=1.5,extrastereo=m=1.8,volume=1.08,alimiter=level_in=1:level_out=0.93:limit=0.96:attack=10:release=100"
93
- -ar 44100 -b:a 256k
94
- `
95
  },
96
 
97
  tiktok_lofi: {
98
- name: "TikTok LoFi (Viral Style)",
99
- description: "Perfect for TikTok - breathing bass, warm vintage",
100
- command: `
101
- -af "asetrate=44100*0.90,atempo=1.111,lowpass=f=4500:p=1,highpass=f=80:p=1,bass=g=7:f=90:w=0.45,equalizer=f=200:t=h:width=150:g=-2,equalizer=f=900:t=h:width=450:g=2,equalizer=f=3200:t=h:width=1800:g=-2.5,equalizer=f=7500:t=h:width=2500:g=-5,acompressor=threshold=-20dB:ratio=4:attack=6:release=120:makeup=4,acrusher=bits=12:mix=0.32:mode=log:aa=0.5,vibrato=f=0.25:d=0.5,aphaser=in_gain=0.6:out_gain=0.88:delay=2.5:decay=0.5:speed=0.45,aecho=0.6:0.72:45:0.3,extrastereo=m=1.65,volume=1.22,alimiter=level_in=1:level_out=0.96:limit=0.99:attack=5:release=45"
102
- -ar 44100 -b:a 256k
103
- `
104
  },
105
 
106
  chill_lofi: {
107
- name: "Chill LoFi (Study Beats)",
108
- description: "Relaxing, smooth, perfect for studying",
109
- command: `
110
- -af "asetrate=44100*0.94,atempo=1.064,lowpass=f=4800:p=1,highpass=f=75:p=1,bass=g=5:f=88:w=0.48,treble=g=-3.5:f=7500:w=0.65,equalizer=f=280:t=h:width=200:g=-1.8,equalizer=f=1200:t=h:width=600:g=1.2,equalizer=f=4000:t=h:width=2000:g=-2.2,acompressor=threshold=-21dB:ratio=3:attack=10:release=150:makeup=2.5,acrusher=bits=13:mix=0.25:mode=log:aa=0.5,vibrato=f=0.2:d=0.42,aecho=0.5:0.65:55:0.25,reverb=roomsize=0.55:damping=0.45:wetlevel=0.28:drylevel=0.72:width=0.85,extrastereo=m=1.5,volume=1.12,alimiter=level_in=1:level_out=0.94:limit=0.97:attack=6:release=55"
111
- -ar 44100 -b:a 256k
112
- `
113
  }
114
  };
115
 
@@ -117,22 +81,19 @@ const EFFECTS = {
117
  app.get('/', (req, res) => {
118
  res.json({
119
  status: 'online',
120
- message: '🎡 LoFi Remix API - Professional Edition v2.0',
121
  version: '2.0',
 
122
  total_effects: Object.keys(EFFECTS).length,
123
  available_effects: Object.keys(EFFECTS).map(key => ({
124
  id: key,
125
- name: EFFECTS[key].name,
126
- description: EFFECTS[key].description
127
  })),
128
  endpoints: {
129
  health: 'GET /',
130
- process: 'POST /process (with audio file + effect param)',
131
  download: 'GET /download/:filename',
132
  effects: 'GET /effects'
133
- },
134
- usage: {
135
- example: 'POST /process with multipart/form-data: audio=<file>&effect=lofi'
136
  }
137
  });
138
  });
@@ -143,24 +104,21 @@ app.get('/effects', (req, res) => {
143
  total: Object.keys(EFFECTS).length,
144
  effects: Object.keys(EFFECTS).map(key => ({
145
  id: key,
146
- name: EFFECTS[key].name,
147
- description: EFFECTS[key].description
148
  }))
149
  });
150
  });
151
 
152
- // 🎡 Process Audio with Selected Effect
153
  app.post('/process', upload.single('audio'), async (req, res) => {
154
  try {
155
  if (!req.file) {
156
  return res.status(400).json({
157
  success: false,
158
- error: 'No audio file uploaded',
159
- hint: 'Send audio file as multipart/form-data with key "audio"'
160
  });
161
  }
162
 
163
- // Get effect from request (default to lofi)
164
  const effectType = req.body.effect || 'lofi';
165
 
166
  if (!EFFECTS[effectType]) {
@@ -168,8 +126,7 @@ app.post('/process', upload.single('audio'), async (req, res) => {
168
  return res.status(400).json({
169
  success: false,
170
  error: `Unknown effect: ${effectType}`,
171
- available_effects: Object.keys(EFFECTS),
172
- hint: 'Use one of the available effect IDs'
173
  });
174
  }
175
 
@@ -178,23 +135,22 @@ app.post('/process', upload.single('audio'), async (req, res) => {
178
  const outputPath = path.join(outputsDir, outputFilename);
179
 
180
  console.log(`🎡 Processing: ${EFFECTS[effectType].name}`);
181
- console.log(`πŸ“ Input: ${req.file.originalname}`);
182
 
183
- // Build FFmpeg command with selected effect
184
- const effectCommand = EFFECTS[effectType].command.replace(/\s+/g, ' ').trim();
185
- const ffmpegCommand = `ffmpeg -i "${inputPath}" ${effectCommand} "${outputPath}"`;
 
186
 
187
- console.log(`βš™οΈ Applying effect...`);
188
 
189
- // Execute FFmpeg
190
  const startTime = Date.now();
191
- await execPromise(ffmpegCommand);
 
 
192
  const processingTime = ((Date.now() - startTime) / 1000).toFixed(2);
193
 
194
- // Clean up input file
195
  fs.unlinkSync(inputPath);
196
 
197
- // Get output file size
198
  const stats = fs.statSync(outputPath);
199
  const fileSizeKB = (stats.size / 1024).toFixed(2);
200
 
@@ -202,38 +158,35 @@ app.post('/process', upload.single('audio'), async (req, res) => {
202
 
203
  res.json({
204
  success: true,
205
- message: `Audio processed successfully with ${EFFECTS[effectType].name}`,
 
 
206
  effect: {
207
  id: effectType,
208
- name: EFFECTS[effectType].name,
209
- description: EFFECTS[effectType].description
210
  },
211
  output: {
212
- filename: outputFilename,
213
- size_kb: fileSizeKB,
214
- download_url: `/download/${outputFilename}`
215
  },
216
  processing_time_seconds: processingTime
217
  });
218
 
219
  } catch (error) {
220
- console.error('❌ Processing error:', error);
221
 
222
- // Clean up on error
223
  if (req.file && fs.existsSync(req.file.path)) {
224
  fs.unlinkSync(req.file.path);
225
  }
226
 
227
  res.status(500).json({
228
  success: false,
229
- error: 'Failed to process audio',
230
- details: error.message,
231
- hint: 'Check if FFmpeg is installed and the audio file is valid'
232
  });
233
  }
234
  });
235
 
236
- // πŸ“₯ Download Processed Audio
237
  app.get('/download/:filename', (req, res) => {
238
  const filename = req.params.filename;
239
  const filePath = path.join(outputsDir, filename);
@@ -241,8 +194,7 @@ app.get('/download/:filename', (req, res) => {
241
  if (!fs.existsSync(filePath)) {
242
  return res.status(404).json({
243
  success: false,
244
- error: 'File not found',
245
- hint: 'File may have been auto-deleted after 10 seconds'
246
  });
247
  }
248
 
@@ -250,11 +202,10 @@ app.get('/download/:filename', (req, res) => {
250
 
251
  res.download(filePath, filename, (err) => {
252
  if (!err) {
253
- // Auto-delete after 10 seconds
254
  setTimeout(() => {
255
  if (fs.existsSync(filePath)) {
256
  fs.unlinkSync(filePath);
257
- console.log(`πŸ—‘οΈ Cleaned up: ${filename}`);
258
  }
259
  }, 10000);
260
  }
@@ -263,11 +214,11 @@ app.get('/download/:filename', (req, res) => {
263
 
264
  // πŸš€ Start Server
265
  app.listen(PORT, '0.0.0.0', () => {
266
- console.log('═══════════════════════════════════════════════════════');
267
- console.log('πŸš€ LoFi Remix API - Professional Edition v2.0');
268
- console.log('═══════════════════════════════════════════════════════');
269
  console.log(`πŸ“ Server: http://0.0.0.0:${PORT}`);
270
- console.log(`🎡 Effects: ${Object.keys(EFFECTS).length} professional presets`);
271
- console.log(`βœ… Status: READY`);
272
- console.log('═══════════════════════════════════════════════════════');
273
  });
 
29
  limits: { fileSize: 50 * 1024 * 1024 }
30
  });
31
 
32
+ // πŸš€ OPTIMIZED EFFECTS - Fast Processing
33
  const EFFECTS = {
34
  lofi: {
35
+ name: "LoFi Hip Hop",
36
+ command: `-filter_complex "[0:a]asetrate=44100*0.92,atempo=1.087,lowpass=f=4200,highpass=f=85,bass=g=6:f=95,treble=g=-4:f=8000,equalizer=f=250:width=180:g=-2.5,equalizer=f=1000:width=500:g=1.5,acompressor=threshold=-22dB:ratio=3.5:attack=8:release=140,vibrato=f=0.22:d=0.45,aecho=0.55:0.68:48:0.28,extrastereo=m=1.5,volume=1.15[out]" -map "[out]" -ar 44100 -b:a 192k`
 
 
 
 
37
  },
38
 
39
  slowed_reverb: {
40
+ name: "Slowed + Reverb",
41
+ command: `-filter_complex "[0:a]atempo=0.82,asetrate=44100*0.93,lowpass=f=6000,highpass=f=70,bass=g=5:f=85,aecho=0.75:0.82:75:0.38,aecho=0.65:0.75:145:0.28,reverb=roomsize=0.92:wetlevel=0.48,chorus=0.6:0.85:52:0.38:0.22:2,acompressor=threshold=-18dB:ratio=2.8:attack=12:release=180,extrastereo=m=1.8,volume=1.25[out]" -map "[out]" -ar 44100 -b:a 192k`
 
 
 
 
42
  },
43
 
44
  nightcore: {
45
+ name: "Nightcore",
46
+ command: `-filter_complex "[0:a]atempo=1.28,asetrate=44100*1.12,highpass=f=120,treble=g=5:f=6000,equalizer=f=4000:width=2000:g=3.5,equalizer=f=8000:width=3000:g=4,acompressor=threshold=-16dB:ratio=3.2:attack=4:release=35,crystalizer=i=1.5,extrastereo=m=1.7,volume=1.28[out]" -map "[out]" -ar 44100 -b:a 192k`
 
 
 
 
47
  },
48
 
49
  vaporwave: {
50
+ name: "Vaporwave",
51
+ command: `-filter_complex "[0:a]asetrate=44100*0.87,atempo=1.15,lowpass=f=5500,highpass=f=90,equalizer=f=400:width=250:g=3.5,equalizer=f=2500:width=1500:g=-1.5,aphaser=in_gain=0.65:out_gain=0.82:delay=4.5:decay=0.55:speed=0.32,chorus=0.68:0.88:58:0.42:0.28:2,vibrato=f=0.18:d=0.5,reverb=roomsize=0.72:wetlevel=0.38,aecho=0.5:0.65:85:0.25,acompressor=threshold=-20dB:ratio=3:attack=10:release=100,extrastereo=m=1.6,volume=1.18[out]" -map "[out]" -ar 44100 -b:a 192k`
 
 
 
 
52
  },
53
 
54
  "8d_audio": {
55
+ name: "8D Audio",
56
+ command: `-filter_complex "[0:a]apulsator=hz=0.085:mode=sine:width=0.92,extrastereo=m=2.8,aecho=0.72:0.85:65:0.38,haas,bass=g=3:f=90,reverb=roomsize=0.65:wetlevel=0.32,acompressor=threshold=-18dB:ratio=2.5:attack=8:release=90,volume=1.12[out]" -map "[out]" -ar 44100 -b:a 192k`
 
 
 
 
57
  },
58
 
59
  bass_boosted: {
60
+ name: "Bass Boosted",
61
+ command: `-filter_complex "[0:a]bass=g=18:f=95,bass=g=12:f=65,equalizer=f=45:width=35:g=10,equalizer=f=100:width=80:g=9,equalizer=f=250:width=150:g=6,acompressor=threshold=-24dB:ratio=6:attack=4:release=45,extrastereo=m=1.4,volume=1.15[out]" -map "[out]" -ar 44100 -b:a 192k`
 
 
 
 
62
  },
63
 
64
  ambient: {
65
+ name: "Ambient Chill",
66
+ command: `-filter_complex "[0:a]asetrate=44100*0.96,atempo=1.042,lowpass=f=7000,highpass=f=60,equalizer=f=2000:width=1500:g=-2.5,reverb=roomsize=0.95:wetlevel=0.55,chorus=0.65:0.88:48:0.42:0.25:3,aecho=0.6:0.75:150:0.32,aphaser=in_gain=0.45:out_gain=0.72:delay=3.8:decay=0.48:speed=0.38,acompressor=threshold=-20dB:ratio=2.2:attack=15:release=200,extrastereo=m=1.8,volume=1.08[out]" -map "[out]" -ar 44100 -b:a 192k`
 
 
 
 
67
  },
68
 
69
  tiktok_lofi: {
70
+ name: "TikTok LoFi",
71
+ command: `-filter_complex "[0:a]asetrate=44100*0.90,atempo=1.111,lowpass=f=4500,highpass=f=80,bass=g=7:f=90,equalizer=f=900:width=450:g=2,equalizer=f=7500:width=2500:g=-5,acompressor=threshold=-20dB:ratio=4:attack=6:release=120,vibrato=f=0.25:d=0.5,aphaser=in_gain=0.6:out_gain=0.88:delay=2.5:decay=0.5:speed=0.45,aecho=0.6:0.72:45:0.3,extrastereo=m=1.65,volume=1.22[out]" -map "[out]" -ar 44100 -b:a 192k`
 
 
 
 
72
  },
73
 
74
  chill_lofi: {
75
+ name: "Chill LoFi",
76
+ command: `-filter_complex "[0:a]asetrate=44100*0.94,atempo=1.064,lowpass=f=4800,highpass=f=75,bass=g=5:f=88,treble=g=-3.5:f=7500,equalizer=f=1200:width=600:g=1.2,acompressor=threshold=-21dB:ratio=3:attack=10:release=150,vibrato=f=0.2:d=0.42,aecho=0.5:0.65:55:0.25,reverb=roomsize=0.55:wetlevel=0.28,extrastereo=m=1.5,volume=1.12[out]" -map "[out]" -ar 44100 -b:a 192k`
 
 
 
 
77
  }
78
  };
79
 
 
81
  app.get('/', (req, res) => {
82
  res.json({
83
  status: 'online',
84
+ message: '🎡 LoFi Remix API v2.0 - Optimized',
85
  version: '2.0',
86
+ performance: 'Fast processing with filter_complex',
87
  total_effects: Object.keys(EFFECTS).length,
88
  available_effects: Object.keys(EFFECTS).map(key => ({
89
  id: key,
90
+ name: EFFECTS[key].name
 
91
  })),
92
  endpoints: {
93
  health: 'GET /',
94
+ process: 'POST /process',
95
  download: 'GET /download/:filename',
96
  effects: 'GET /effects'
 
 
 
97
  }
98
  });
99
  });
 
104
  total: Object.keys(EFFECTS).length,
105
  effects: Object.keys(EFFECTS).map(key => ({
106
  id: key,
107
+ name: EFFECTS[key].name
 
108
  }))
109
  });
110
  });
111
 
112
+ // 🎡 Process Audio
113
  app.post('/process', upload.single('audio'), async (req, res) => {
114
  try {
115
  if (!req.file) {
116
  return res.status(400).json({
117
  success: false,
118
+ error: 'No audio file uploaded'
 
119
  });
120
  }
121
 
 
122
  const effectType = req.body.effect || 'lofi';
123
 
124
  if (!EFFECTS[effectType]) {
 
126
  return res.status(400).json({
127
  success: false,
128
  error: `Unknown effect: ${effectType}`,
129
+ available_effects: Object.keys(EFFECTS)
 
130
  });
131
  }
132
 
 
135
  const outputPath = path.join(outputsDir, outputFilename);
136
 
137
  console.log(`🎡 Processing: ${EFFECTS[effectType].name}`);
 
138
 
139
+ const effectCommand = EFFECTS[effectType].command;
140
+
141
+ // Optimized FFmpeg command with faster settings
142
+ const ffmpegCommand = `ffmpeg -i "${inputPath}" -threads 0 ${effectCommand} -y "${outputPath}"`;
143
 
144
+ console.log(`βš™οΈ Starting FFmpeg...`);
145
 
 
146
  const startTime = Date.now();
147
+ await execPromise(ffmpegCommand, {
148
+ maxBuffer: 50 * 1024 * 1024 // 50MB buffer
149
+ });
150
  const processingTime = ((Date.now() - startTime) / 1000).toFixed(2);
151
 
 
152
  fs.unlinkSync(inputPath);
153
 
 
154
  const stats = fs.statSync(outputPath);
155
  const fileSizeKB = (stats.size / 1024).toFixed(2);
156
 
 
158
 
159
  res.json({
160
  success: true,
161
+ message: `Processed with ${EFFECTS[effectType].name}`,
162
+ downloadUrl: `/download/${outputFilename}`,
163
+ filename: outputFilename,
164
  effect: {
165
  id: effectType,
166
+ name: EFFECTS[effectType].name
 
167
  },
168
  output: {
169
+ size_kb: fileSizeKB
 
 
170
  },
171
  processing_time_seconds: processingTime
172
  });
173
 
174
  } catch (error) {
175
+ console.error('❌ Error:', error);
176
 
 
177
  if (req.file && fs.existsSync(req.file.path)) {
178
  fs.unlinkSync(req.file.path);
179
  }
180
 
181
  res.status(500).json({
182
  success: false,
183
+ error: 'Processing failed',
184
+ details: error.message
 
185
  });
186
  }
187
  });
188
 
189
+ // πŸ“₯ Download
190
  app.get('/download/:filename', (req, res) => {
191
  const filename = req.params.filename;
192
  const filePath = path.join(outputsDir, filename);
 
194
  if (!fs.existsSync(filePath)) {
195
  return res.status(404).json({
196
  success: false,
197
+ error: 'File not found'
 
198
  });
199
  }
200
 
 
202
 
203
  res.download(filePath, filename, (err) => {
204
  if (!err) {
 
205
  setTimeout(() => {
206
  if (fs.existsSync(filePath)) {
207
  fs.unlinkSync(filePath);
208
+ console.log(`πŸ—‘οΈ Cleaned: ${filename}`);
209
  }
210
  }, 10000);
211
  }
 
214
 
215
  // πŸš€ Start Server
216
  app.listen(PORT, '0.0.0.0', () => {
217
+ console.log('═══════════════════════════════════════');
218
+ console.log('πŸš€ LoFi Remix API v2.0 - OPTIMIZED');
219
+ console.log('═══════════════════════════════════════');
220
  console.log(`πŸ“ Server: http://0.0.0.0:${PORT}`);
221
+ console.log(`⚑ Performance: Fast processing enabled`);
222
+ console.log(`🎡 Effects: ${Object.keys(EFFECTS).length}`);
223
+ console.log('═══════════════════════════════════════');
224
  });