Skip to content

buriihenry/music-gen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Music Generator App

A full‑stack music generation app. Users describe a song (or provide lyrics/prompts), and the system generates audio and a cover image using an AI backend, stores them in S3, and manages tracks, categories, and publishing in a PostgreSQL database.

Tech Stack

  • Frontend: Next.js 15 (App Router), React 19, TypeScript, Tailwind CSS, Radix UI, Zustand
  • Auth: Better Auth + Prisma adapter
  • DB: Neon (PostgreSQL) via Prisma 6
  • Jobs/Orchestration: Inngest
  • Storage: AWS S3 (audio .wav and cover images .png)
  • AI Backend: Python (Modal), PyTorch, Transformers, Diffusers, ACE‑Step pipeline, Qwen2‑7B, SDXL‑Turbo

Repository Structure

./
├── backend/
│   ├── main.py                 # Modal app: model loading, endpoints, S3 uploads
│   ├── prompts.py              # LLM prompt templates
│   └── requirements.txt        # Python deps
└── frontend/
    ├── prisma/schema.prisma    # Prisma models: User, Song, Category, Like, etc.
    ├── src/
    │   ├── actions/            # Server Actions (generation, song ops)
    │   ├── app/                # Next.js routes (auth, main, API)
    │   ├── components/         # UI (create flow, track list, player UI)
    │   ├── inngest/            # Inngest client + functions
    │   ├── lib/                # auth, utils
    │   ├── server/db.ts        # Prisma client
    │   └── stores/             # Zustand player store
    ├── next.config.js          # Next.js config (remote image hosts)
    ├── src/env.js              # Env validation (@t3-oss/env-nextjs)
    └── package.json

Core Flow

  1. User signs in (Better Auth). Main routes require a session.
  2. User submits a request (full description OR prompt+lyrics OR prompt+described lyrics).
  3. A Server Action creates Song rows with status queued and sends an Inngest event.
  4. Inngest function selects the appropriate Modal endpoint, sets status=processing, calls the backend.
  5. Backend generates audio and a cover image, uploads both to S3, returns S3 keys and detected categories.
  6. Inngest updates the Song with s3key, thumbnails3key, status, and connects categories; decrements user credits.
  7. UI lists tracks; clicking a processed track fetches a presigned URL and plays/downloads it.

Database Models (Prisma)

  • User: id, email, image, auth metadata, credits (default 100)
  • Song: title, s3key, thumbnails3key, status, instrumental, prompt/lyrics fields, params, published, listenCount, categories, userId
  • Category: name (unique), many‑to‑many with songs
  • Like: composite key (userId, songId)
  • Auth tables: Session, Account, Verification

Environment Variables

Validated in frontend/src/env.js.

Required (server side):

  • BETTER_AUTH_SECRET
  • BETTER_AUTH_URL
  • DATABASE_URL (Neon PostgreSQL connection string)
  • NODE_ENV (development|test|production)
  • MODAL_KEY, MODAL_SECRET (Modal proxy auth)
  • AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY_ID (credentials used for presigning)
  • AWS_REGION (e.g., eu-central-1 — must match the bucket’s region)
  • S3_BUCKET_NAME (no spaces)
  • GENERATE_FROM_DESCRIPTION
  • GENERATE_FROM_DESCRIBED_LYRICS
  • GENERATE_WITH_LYRICS

Notes:

  • Bucket name must not include spaces or leading/trailing whitespace.
  • The app presigns S3 GET URLs on the server using the above credentials.

Setup

1) Frontend

cd frontend
npm install
npm run db:generate   # prisma migrate dev (or adjust to your workflow)

Ensure .env exists in frontend/ with all server variables above.

2) Database

  • Create a Neon database and set DATABASE_URL (Neon provides PostgreSQL connection strings).
  • Run migrations:
cd frontend
npm run db:migrate    # or: npm run db:push for non-migration dev flow

3) AWS S3

  • Create an S3 bucket and set S3_BUCKET_NAME and AWS_REGION.
  • Ensure the IAM user (access key/secret) has permissions for s3:GetObject and s3:PutObject for that bucket.

4) Modal (AI Backend)

  • Install Modal CLI and authenticate.
  • The Python service is defined in backend/main.py. It uses Modal’s @app.cls with GPU and @modal.fastapi_endpoint endpoints.
  • Expose endpoints and set their URLs in:
    • GENERATE_FROM_DESCRIPTION
    • GENERATE_FROM_DESCRIBED_LYRICS
    • GENERATE_WITH_LYRICS

5) Inngest

  • The Inngest API route is served from Next at src/app/api/inngest/route.ts.
  • Configure Inngest project as needed; the client id is music-gen in src/inngest/client.ts.

Running Locally

In one terminal (frontend):

cd frontend
npm run dev

This starts Next.js. Sign in at /auth/sign-in.

Modal backend runs on Modal’s infra. Ensure your env variables point to the live endpoints. If running locally for testing, adapt the endpoints accordingly.

Key Commands (frontend)

  • npm run dev — Start dev server
  • npm run build && npm start — Production build/start
  • npm run db:generateprisma migrate dev
  • npm run db:migrateprisma migrate deploy
  • npm run db:push — Push schema without migrations (dev only)
  • npm run db:studio — Prisma Studio
  • npm run check — Lint + typecheck

Configuration Notes

  • next.config.js allows remote images. If using next/image, ensure the hostname matches your S3 URL pattern, e.g. **.s3.eu-central-1.amazonaws.com.
  • The app currently uses standard <img> tags in the track list.

Troubleshooting

  • Thumbnails don’t load / 400/403 on presigned URL
    • Check for spaces in S3_BUCKET_NAME. Trailing spaces produce InvalidBucketName and %20 in the URL.
    • Ensure AWS_REGION matches the bucket region exactly.
    • Verify presigner uses correct credentials:
      • accessKeyId = AWS_ACCESS_KEY_ID
      • secretAccessKey = AWS_SECRET_ACCESS_KEY_ID (variable name as defined in env)
    • Keys must not start with /. The app sanitizes leading slashes.
  • Image downloads but doesn’t render
    • Set content type when uploading in backend:
      s3_client.upload_file(image_output_path, bucket_name, image_s3_key,
                            ExtraArgs={"ContentType": "image/png"})
    • Regenerate after fixing metadata (existing objects keep old metadata).
  • Audio playback fails
    • The presigned audio URL comes from getPlayUrl. Confirm s3key exists and user is authorized.
  • No credits
    • Inngest sets status = "no credits" when User.credits <= 0.
  • Job failures
    • Inngest onFailure sets status = "failed". Check Modal logs and Next server logs.

Security Considerations

  • Server Actions and Inngest calls run server-side and use server env vars.
  • Presigned URLs expire after 1 hour (expiresIn: 3600). Adjust as needed.
  • Ensure Modal endpoints require proxy auth and env secrets are set.

License

MIT (or your preferred license).

About

Full-stack music generation app. Users describe or provide lyrics/prompts to generate songs.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors