# Pay2Play! — The Worst Music Player A satirical music player where every interaction is paywalled. Pause? That's $0.01. Resume? Separate charge. Turn off repeat? That costs *more* than turning it on. Part of [donothireus.com](https://donothireus.com). ## Quick start No build step, no package manager. Just serve the `public/` directory: ```bash cd public/ python3 -m http.server 8080 # open http://localhost:8080 ``` Or with any other static file server (Caddy, nginx, etc). ## Project structure ``` public/ ├── index.html # HTML shell, CDN script tags, meta/OG tags ├── style.css # Animations, hover/focus states, range styling ├── app.js # All React components and logic (JSX via Babel) └── audio/ # Drop MP3 files here for real music ├── songs.json # Generated by tools/probe-songs.py (gitignored) └── .gitkeep tools/ └── probe-songs.py # Probe audio files → songs.json ``` ## Deploying to donothireus.com Just serve the `public/` directory. If you're using Caddy (which I know you are), something like: ``` donothireus.com { root * /srv/donothireus/public file_server encode gzip } ``` Or to put it at a subpath like `/payplay`: ``` donothireus.com { handle /payplay/* { root * /srv/donothireus/payplay/public uri strip_prefix /payplay file_server } } ``` ## Audio: procedural vs real music By default the player uses Tone.js to generate procedural synth loops — no external audio files needed. This is funny on its own ("even the songs are cheaply made") but you can swap in real CC-licensed tracks. ### Switching to self-hosted MP3s 1. Download CC-BY licensed MP3s (see sources below) 2. Put them in `public/audio/` 3. Run the probe tool to generate `songs.json`: ```bash ./tools/probe-songs.py -d public/audio # Writes public/audio/songs.json automatically ``` The app fetches `audio/songs.json` on startup. If it exists and contains tracks, they replace the procedural builtins. If not, the synth songs are used as a fallback. The generated JSON looks like: ```json [ { "title": "Sneaky Snitch", "artist": "Kevin MacLeod", "duration": 120, "url": "/audio/sneaky-snitch.mp3", "color": "#e74c3c" } ] ``` Title and artist are extracted from ID3 tags when available, falling back to the filename. Duration comes from ffprobe. You can also probe specific files or write to a custom path: ```bash ./tools/probe-songs.py public/audio/track1.mp3 public/audio/track2.mp3 ./tools/probe-songs.py -o public/audio/songs.json *.mp3 ``` ### Where to get CC-BY music All of these are free to use with attribution (CC-BY or CC0): **Kevin MacLeod / Incompetech** (CC-BY 4.0) - https://incompetech.com/music/royalty-free/ - Thousands of tracks, well-known, easy to search by mood/genre - Attribution: "Title" Kevin MacLeod (incompetech.com) Licensed under Creative Commons: By Attribution 4.0 - Also mirrored on archive.org: https://archive.org/details/Incompetech **Free Music Archive** (various CC licenses — filter for CC-BY) - https://freemusicarchive.org/ - Filter by license type, download MP3s directly - Check each track's specific license **SampleSwap** (CC-BY-NC-SA for most tracks) - https://sampleswap.org/mp3/creative-commons/free-music.php - 320kbps MP3s, various genres **Pixabay Music** (Pixabay License — free, no attribution required) - https://pixabay.com/music/ - No API key needed for downloads, but no hotlinking ### Download and host workflow ```bash # Example: grab a Kevin MacLeod track cd public/audio/ wget -O sneaky-snitch.mp3 "https://incompetech.com/music/royalty-free/mp3-royaltyfree/Sneaky%20Snitch.mp3" # Generate songs.json from all audio in the directory cd ../.. ./tools/probe-songs.py -d public/audio ``` ### Attribution If using CC-BY music, add attribution. The fine print at the bottom of the player is a good place, or add a separate credits section. Kevin MacLeod's required format: > "Track Title" Kevin MacLeod (incompetech.com) > Licensed under Creative Commons: By Attribution 4.0 > https://creativecommons.org/licenses/by/4.0/ ## How it works - React 18 loaded from CDN, JSX compiled by Babel standalone - Tone.js for procedural synth audio (no build step needed) - HTML5 Audio API for self-hosted MP3 playback - Zero dependencies to install, zero build tools - All state is client-side, nothing persisted The starting wallet is randomized between $0.50 and $10.00 each page load. The +$10 button lets people keep exploring all the paywalls (with a $0.50 processing fee, naturally). ## License Do whatever you want with this. It's a joke.