Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ShuttleLab/music-shuttle

Repository files navigation

Music Shuttle

A serverless music player built with Next.js and Cloudflare R2.
Live: music.shuttlelab.org

Features

  • Multiple formats: MP3, M4A, WAV, OGG, FLAC, MP4
  • Shuffle and sequential playback
  • Seekable progress bar
  • Search
  • Responsive layout (mobile & desktop)
  • Cloud storage via Cloudflare R2
  • Smart cache (Cache API) and prefetch for fast/offline playback

Tech Stack

  • Frontend: Next.js 15, React 19, TypeScript, Tailwind CSS
  • Audio: HTML5 Audio, Range requests (streaming), Cache API
  • Backend: Next.js API Routes, Cloudflare R2 (S3-compatible)

Project Structure

music-shuttle/
├── app/
│ ├── api/audio/route.ts # GET /api/audio?key=...
│ ├── api/list/route.ts # GET /api/list
│ ├── layout.tsx
│ ├── page.tsx
│ └── globals.css
├── components/player/MusicPlayer.tsx
├── lib/
│ ├── hooks/ # useMusicList, useAudioPlayer, useAudioCache, useAudioPrefetch
│ └── utils.ts
├── .env.local.example
└── wrangler.toml # R2 binding for Cloudflare

Quick Start

Requirements: Node.js 18+, npm/pnpm, Cloudflare account, R2 bucket with audio files.

git clone <your-repo-url>
cd music-shuttle
npm install
npm run dev

Open http://localhost:3000.
Note: R2 APIs need Cloudflare; for full behavior, deploy to Cloudflare Pages.

Deploy to Cloudflare Pages

  1. Connect repo to Cloudflare Pages.

  2. Build command: npx @cloudflare/next-on-pages@1

  3. Output directory: .vercel/output/static

  4. In wrangler.toml, set R2 binding:

    compatibility_flags = ["nodejs_compat"]
    [[r2_buckets]]
    binding = "R2_BUCKET"
    bucket_name = "your-bucket-name"

No API keys needed; R2 is accessed via bindings.
Full guide: CLOUDFLARE_DEPLOYMENT.md

Commands

Command Description
npm run dev Start dev server
npm run build Local build
npm run pages:build Build for Cloudflare Pages
npm run lint Lint

API (after deploy)

  • List: GET /api/list — optional: ?prefix=..., ?limit=N, ?demo=1, ?debug=1
  • Audio: GET /api/audio?key=filename.mp3 — supports Range for streaming

FAQ

  • Empty list? Check R2 binding in wrangler.toml, bucket name, and that files have supported extensions (.mp3, .m4a, .wav, .ogg, .flac, .mp4).
  • Two requests per track? One is streaming (instant play), one is full prefetch for cache; this is intentional.
  • Clear cache: DevTools → Application → Cache Storage → delete music-shuttle-v1, or run caches.delete('music-shuttle-v1') in console.

Contributing

  1. Fork the repo
  2. Create a branch: git checkout -b feature/your-feature
  3. Commit and push, then open a Pull Request

License

MIT

AltStyle によって変換されたページ (->オリジナル) /