Fix audio playback for newly uploaded files by using dynamic API route
This commit is contained in:
@@ -561,7 +561,7 @@ export default function AdminPage() {
|
|||||||
audioElement?.pause();
|
audioElement?.pause();
|
||||||
|
|
||||||
// Play new song
|
// Play new song
|
||||||
const audio = new Audio(`/uploads/${song.filename}`);
|
const audio = new Audio(`/api/audio/${song.filename}`);
|
||||||
|
|
||||||
// Handle playback errors
|
// Handle playback errors
|
||||||
audio.onerror = () => {
|
audio.onerror = () => {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export async function GET() {
|
|||||||
title: puzzle.song.title,
|
title: puzzle.song.title,
|
||||||
artist: puzzle.song.artist,
|
artist: puzzle.song.artist,
|
||||||
filename: puzzle.song.filename,
|
filename: puzzle.song.filename,
|
||||||
audioUrl: `/uploads/${puzzle.song.filename}`
|
audioUrl: `/api/audio/${puzzle.song.filename}`
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
35
app/api/audio/[filename]/route.ts
Normal file
35
app/api/audio/[filename]/route.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
import { readFile, stat } from 'fs/promises';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: NextRequest,
|
||||||
|
{ params }: { params: Promise<{ filename: string }> }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const { filename } = await params;
|
||||||
|
const filePath = path.join(process.cwd(), 'public/uploads', filename);
|
||||||
|
|
||||||
|
// Check if file exists
|
||||||
|
try {
|
||||||
|
await stat(filePath);
|
||||||
|
} catch {
|
||||||
|
return new NextResponse('File not found', { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read file
|
||||||
|
const fileBuffer = await readFile(filePath);
|
||||||
|
|
||||||
|
// Return with proper headers
|
||||||
|
return new NextResponse(fileBuffer, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'audio/mpeg',
|
||||||
|
'Accept-Ranges': 'bytes',
|
||||||
|
'Cache-Control': 'public, max-age=3600, must-revalidate',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error serving audio file:', error);
|
||||||
|
return new NextResponse('Internal Server Error', { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -98,7 +98,7 @@ export async function getOrCreateDailyPuzzle(genreName: string | null = null) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: dailyPuzzle.id,
|
id: dailyPuzzle.id,
|
||||||
audioUrl: `/uploads/${dailyPuzzle.song.filename}`,
|
audioUrl: `/api/audio/${dailyPuzzle.song.filename}`,
|
||||||
songId: dailyPuzzle.songId,
|
songId: dailyPuzzle.songId,
|
||||||
title: dailyPuzzle.song.title,
|
title: dailyPuzzle.song.title,
|
||||||
artist: dailyPuzzle.song.artist,
|
artist: dailyPuzzle.song.artist,
|
||||||
@@ -185,7 +185,7 @@ export async function getOrCreateSpecialPuzzle(specialName: string) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: dailyPuzzle.id,
|
id: dailyPuzzle.id,
|
||||||
audioUrl: `/uploads/${dailyPuzzle.song.filename}`,
|
audioUrl: `/api/audio/${dailyPuzzle.song.filename}`,
|
||||||
songId: dailyPuzzle.songId,
|
songId: dailyPuzzle.songId,
|
||||||
title: dailyPuzzle.song.title,
|
title: dailyPuzzle.song.title,
|
||||||
artist: dailyPuzzle.song.artist,
|
artist: dailyPuzzle.song.artist,
|
||||||
|
|||||||
Reference in New Issue
Block a user