Skip to content

Repository files navigation

Earshot

License: MIT Next.js TypeScript

Earshot — personal audio library. Books transformed into multi-episode podcasts, streamed from R2, with per-user listening position saved across devices.

Live at https://earshot.haimdimer.com.

Stack

  • Next.js 16 (App Router, Turbopack)
  • NextAuth v5 — Credentials provider (email + bcrypt)
  • Neon Postgres (via the @neondatabase/serverless HTTP driver, so cold-start friendly on Vercel)
  • Cloudflare R2 for audio storage, S3-compatible API, Range request support
  • Tailwind v4
  • Deployed on Vercel (auto-deploys from main)

What it does

Each book is a row in books. Episodes are rows in episodes, each with a unique audio_key matching an R2 object (<audio_key>.mp3). When you play an episode, the audio player throttles timeupdate to save your position every 5 seconds (locally and to the server). pause, seeked, and pagehide (via navigator.sendBeacon) all save too. Position is keyed on (user_email, audio_key) so you resume from any device.

See CLAUDE.md for the architecture detail.

Local dev

cp .env.example .env.local
# Fill in DATABASE_URL, AUTH_SECRET (openssl rand -base64 32), R2_* creds
npx tsx scripts/apply-schema.ts
npm run dev

Sign up at /signup, then /.

Adding a book

  1. Generate the episodes with the podcast Claude skill.
  2. Pick a slug (e.g. getting-to-we). Save a 600x800-ish cover at public/covers/<slug>.jpg.
  3. Upload each MP3 to R2:
    wrangler r2 object put "library-audio/<slug>-ep1.mp3" --file ep1/ep1-podcast.mp3 --content-type audio/mpeg --remote
  4. Write a seed script modeled on scripts/seed-getting-to-we.ts, point DATABASE_URL at prod, run it.

Acknowledgement

The audio player and position-tracking schema were ported from an internal audio feature I had built previously; same UX, rebuilt on a different backend.

About

Turn books into multi-episode podcasts. Next.js 16, Neon Postgres, Cloudflare R2, NextAuth. Personal audio library with admin + per-user resume.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages