Skip to main content
Glama
10-streaming-downloads.md5.67 kB
# Streaming & Download API ## Overview Stream and download audio files from the Navidrome server. These endpoints are primarily accessed through the Subsonic API. ## Streaming Endpoints ### GET /rest/stream Stream an audio file with optional transcoding. **Parameters:** - `id` (required): Song/track ID - `u` (required): Username - `p` (required): Password (plain text or token) - `v` (required): API version (e.g., "1.16.1") - `c` (required): Client application name - `maxBitRate` (optional): Maximum bitrate in kbps - `format` (optional): Target format (mp3, aac, opus, etc.) - `timeOffset` (optional): Start time in seconds - `size` (optional): Requested file size limit **Example:** ``` GET /rest/stream?id=123&u=user&p=pass&v=1.16.1&c=MyApp GET /rest/stream?id=123&u=user&p=pass&v=1.16.1&c=MyApp&maxBitRate=192&format=mp3 ``` **Response:** - Content-Type: `audio/mpeg`, `audio/aac`, `audio/ogg`, etc. - Stream headers: - `Content-Length`: File size in bytes - `Accept-Ranges: bytes`: Supports range requests - `X-Content-Duration`: Duration in seconds - `Last-Modified`: File modification time **Range Support:** ``` Range: bytes=0-1023 ``` Returns partial content for seeking/resuming. ### GET /rest/download Download original audio file without transcoding. **Parameters:** Same as `/rest/stream` but: - No transcoding applied - Always returns original file format - Sets download disposition header **Response Headers:** - `Content-Disposition: attachment; filename="song.mp3"` - `Content-Type`: Original file MIME type ## Native API Streaming ### Pattern Recognition While streaming primarily uses Subsonic API, the native API follows patterns: **Potential Endpoints** (verify with server): - `/api/stream/{id}`: Direct streaming - `/api/download/{id}`: Direct download - `/api/song/{id}/stream`: Song streaming - `/api/song/{id}/download`: Song download ## Stream URL Generation ### For Subsonic API ```javascript const streamUrl = `/rest/stream?` + new URLSearchParams({ id: songId, u: username, p: password, // or token v: '1.16.1', c: 'MyClient', maxBitRate: maxBitRate || '', format: format || '' }).toString() ``` ### For Native API (with auth token) ```javascript const streamUrl = `/api/stream/${songId}?maxBitRate=${maxBitRate}&format=${format}` // Include X-ND-Authorization header ``` ## Transcoding Parameters ### Quality Selection | Bitrate | Quality | Use Case | |---------|---------|----------| | 64-96k | Low | Mobile data | | 128k | Standard | General streaming | | 192k | Good | WiFi streaming | | 320k | High | High-quality playback | | 0 | Original | No transcoding | ### Format Options - `mp3`: Universal compatibility - `aac`: iOS/Safari optimized - `opus`: Best compression - `ogg`: Open standard - Empty: Server decides ## Range Requests ### Seeking Support ```http Range: bytes=1024000-2048000 ``` Returns: ```http 206 Partial Content Content-Range: bytes 1024000-2048000/5086594 Content-Length: 1024000 ``` ### Progressive Loading ```javascript // Load first 64KB for fast start fetch(streamUrl, { headers: { 'Range': 'bytes=0-65535' } }) // Continue loading in chunks fetch(streamUrl, { headers: { 'Range': 'bytes=65536-131071' } }) ``` ## Audio Formats Support ### Input Formats - **FLAC**: Lossless, high quality - **MP3**: Universal support - **AAC**: Apple ecosystem - **OGG/Vorbis**: Open standard - **Opus**: Modern codec - **ALAC**: Apple lossless - **WMA**: Windows Media - **WAV**: Uncompressed ### Browser Compatibility | Format | Chrome | Firefox | Safari | Edge | |--------|--------|---------|--------|------| | MP3 | ✓ | ✓ | ✓ | ✓ | | AAC | ✓ | ✓ | ✓ | ✓ | | OGG | ✓ | ✓ | ✗ | ✓ | | Opus | ✓ | ✓ | ✗ | ✓ | | FLAC | ✓ | ✓ | ✓ | ✓ | ## Performance Optimization ### Client-Side ```javascript // Preload next track const preloadUrl = generateStreamUrl(nextSongId) const audio = new Audio() audio.preload = 'metadata' audio.src = preloadUrl // Use appropriate bitrate for connection const maxBitRate = navigator.connection?.effectiveType === '4g' ? 320 : 128 ``` ### Caching Headers Response includes cache headers: - `Last-Modified`: File timestamp - `ETag`: File hash/version - `Cache-Control`: Caching policy Use conditional requests: ```http If-Modified-Since: Mon, 02 Nov 2015 02:06:44 GMT If-None-Match: "abc123def456" ``` ## Error Handling ### Common HTTP Status Codes - `200 OK`: Successful stream - `206 Partial Content`: Range request - `304 Not Modified`: Cached version current - `401 Unauthorized`: Invalid credentials - `404 Not Found`: Song not found - `416 Range Not Satisfiable`: Invalid range - `500 Internal Server Error`: Transcoding failed ### Retry Logic ```javascript const streamWithRetry = async (url, attempts = 3) => { for (let i = 0; i < attempts; i++) { try { const response = await fetch(url) if (response.ok) return response if (response.status === 404) break // Don't retry 404 } catch (error) { if (i === attempts - 1) throw error await new Promise(resolve => setTimeout(resolve, 1000 * i)) } } throw new Error('Stream failed after retries') } ``` ## Security Considerations ### Authentication - Subsonic API: Username/password in URL parameters - Native API: JWT token in headers (more secure) - Consider HTTPS for credential protection ### Access Control - Users can only stream their accessible music - Sharing links bypass user authentication - Server may log streaming activity ### Rate Limiting - Servers may limit concurrent streams per user - Bandwidth throttling based on server configuration - Consider user's subscription limits

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Blakeem/Navidrome-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server