- Create /api/audio endpoint for upload/get/delete operations - Add AudioPlayer component with custom controls - Add AudioUpload component for admin interface - Update admin page with audio upload UI and indicators - Update main blog page to use new AudioPlayer component - Add database migration for audio_url and audio_duration columns - Add comprehensive documentation in docs/MP3_AUDIO_FEATURE.md - Update README with audio feature overview
5.1 KiB
MP3 Audio Hosting Feature
This document describes the MP3 audio hosting functionality added to the blog-backup project.
Overview
The blog now supports uploading and hosting MP3 audio files for individual blog posts. This allows you to:
- Upload custom MP3 files to any blog post
- Attach audio commentary, interviews, or supplementary content
- Automatically estimate audio duration
- Play audio directly in the blog post with a custom audio player
Features
1. Supabase Storage Integration
- Bucket:
podcast-audio(shared with podcast feature) - File Size Limit: 50MB per file
- Supported Formats: MP3, WAV, AIFF
- Public Access: Files are publicly readable via signed URLs
2. API Endpoints
GET /api/audio?postId={id}
Retrieves audio information for a blog post.
Response:
{
"hasAudio": true,
"audioUrl": "https://...",
"duration": 180
}
POST /api/audio
Uploads an audio file and associates it with a blog post.
Request:
- Content-Type:
multipart/form-data - Authorization:
Bearer {token} - Body:
file(audio file),postId(string)
Response:
{
"success": true,
"url": "https://...",
"path": "upload-2026-02-25-123456789-1740523456789.mp3",
"size": 5242880,
"estimatedDuration": 327
}
DELETE /api/audio
Removes audio from a blog post and deletes the file from storage.
Request:
- Authorization:
Bearer {token} - Body:
{ "postId": "..." }
3. Database Schema
The blog_messages table now includes:
audio_url(text, nullable) - Public URL to the audio fileaudio_duration(integer, nullable) - Estimated duration in seconds
4. Components
AudioPlayer
Located in src/components/AudioPlayer.tsx
A custom audio player with:
- Play/pause controls
- Progress bar with seek functionality
- Volume control with mute toggle
- Time display (current / total)
- Dark mode support
Usage:
import { AudioPlayer } from "@/components/AudioPlayer";
<AudioPlayer
url="https://..."
duration={180} // optional
/>
CompactAudioPlayer
A minimal version for inline use:
import { CompactAudioPlayer } from "@/components/AudioPlayer";
<CompactAudioPlayer url="https://..." />
AudioUpload
Located in src/components/AudioUpload.tsx
Upload component for the admin interface with:
- Drag-and-drop file selection
- File type validation
- File size validation (50MB max)
- Upload progress indicator
- Current audio preview
- Remove/delete functionality
Usage:
import { AudioUpload } from "@/components/AudioUpload";
<AudioUpload
postId="123"
existingAudioUrl={post.audio_url}
onUploadSuccess={(url, duration) => {}}
onDeleteSuccess={() => {}}
/>
5. Admin Interface
The admin dashboard (/admin) now includes:
- Audio indicator badge on posts with audio
- Audio upload section in the edit modal
- Preview player for uploaded audio
- Remove audio functionality
Usage Guide
Adding Audio to a Post
- Go to
/adminand log in - Find the post you want to add audio to
- Click "Edit"
- Scroll to the "Audio Attachment" section
- Click to upload or drag and drop an MP3 file
- Wait for upload to complete
- Save changes
Removing Audio from a Post
- Go to
/adminand log in - Edit the post with audio
- In the "Audio Attachment" section, click "Remove"
- Confirm deletion
- Save changes
Viewing Audio on the Blog
- Posts with audio display a 🎧 icon in the admin list
- On the public blog, audio appears at the top of the post
- The custom audio player provides full playback controls
Technical Details
File Naming
Uploaded files are named with the pattern:
upload-{date}-{postId}-{timestamp}.{ext}
Example: upload-2026-02-25-123456789-1740523456789.mp3
Duration Estimation
Since extracting exact MP3 duration server-side requires additional libraries, we estimate duration based on file size:
- Assumption: 128 kbps bitrate (standard for MP3)
- Formula:
duration = (fileSize / (128 * 1024 / 8)) * 60
The browser will display the actual duration once the audio file loads.
Storage Costs
- Supabase free tier includes 1GB storage
- At 128kbps, 1GB = ~17.5 hours of audio
- Podcast audio and uploaded MP3s share the same bucket
Future Enhancements
Potential improvements:
- Exact Duration Extraction: Use
music-metadatalibrary for accurate duration - Multiple Audio Files: Support for multiple audio tracks per post
- Audio Transcription: Auto-generate transcripts from audio
- Waveform Visualization: Display audio waveforms
- Download Button: Allow users to download audio files
Troubleshooting
Upload fails
- Check that file is under 50MB
- Verify file is a valid audio format (MP3, WAV, AIFF)
- Ensure you're logged in with a valid session
Audio doesn't play
- Check browser console for errors
- Verify audio_url is accessible in the database
- Test the direct URL in a new tab
Duration shows 0:00
- This is normal for the initial display
- The actual duration loads when the audio file is fetched
- Duration is estimated from file size for the initial display