Skip to content
raysanjeev19Public

About

आर्केस्ट्रा — a Bhojpuri stage-night radio. The songs an orchestra plays at a wedding in Bihar, in blocks, through the night. Astro, vanilla JS, YouTube-backed.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

आर्केस्ट्रा · arkestra

A Bhojpuri stage-night radio. The songs a hired आर्केस्ट्रा plays at a wedding in Bihar — in blocks, through the night, in the order a real programme runs them.

Not a music player with a Bihar skin. The structure of the night is the product.

The stage


Two ideas

रात का क्लॉक — the night clock

The site reads your clock and plays what an orchestra would be playing at that hour. The scene retints with it.

Local time Block Scene
5–9 pm साउंड चेक Tubelights half-on, sky still blue
9 pm–12 am मंच पूजा · देवी गीत Full tubelights, nobody standing yet
12–1 am शादी–तिलक नाइट Par cans in, crowd up
1–3 am डीजे ब्लॉक Strobes, thick beams
3–5 am दर्द ब्लॉक Lights go warm and low
5 am–5 pm भोरहरी Sky greys, tubelights coming down

It's a default, not a cage — pick a playlist and the clock stops steering. And it never switches mid-song: the running order is rebuilt for the new block and the current track is allowed to finish.

डीजे ब्लॉक — strobes and thick beams दर्द ब्लॉक — warm and low

No fabricated listener count

Sibling sites in this genre show a live-looking listener number that is actually a random walk. A made-up number sitting next to a rights-and-takedown notice isn't a detail worth inheriting. The block name replaces it, and the block name is true — derived from your device clock and nothing else.


The scene is drawn, not photographed

The stage is a hand-authored SVG: bamboo-and-plank deck, the tubelight ladder zip-tied across the front, column speakers, the magenta-and-cyan flex backdrop, a bamboo truss of par cans, dust in the beams, backs of heads in the crowd. It costs 7 KB inlined in the HTML instead of a 250 KB photograph, stays sharp at any size, retints by the hour, and the speaker cones move while the music plays.

The YouTube player is the LED wall behind the stage — visible, in the scene, graded to match the night. Real setups have one, and a visible player is what YouTube's terms contemplate.

Playing


On what this is a tribute to

The commercial arkestra trade has a well-documented cost: reporting by The Print, PARI, 101Reporters and others records widespread trafficking of women and girls into orchestra groups. Bihar Police rescued 162 girls from the so-called orchestra belt in the first half of 2025 alone.

That's not a reason to drop the homage. It's a reason to be precise about who it's to.

The protagonists here are the crew — the बजनिया at the octapad, the dholak player warming the skin over a fire so the pitch comes up, the anchor with his folded sheet of names, the light-wala, the generator man. Their craft is real, their labour is chosen, and celebrating them costs nobody anything.

So there are no dancers in the artwork and there will not be any. No item-song visual language, no notes showered on a performer, no firearms, no double-meaning songs in the catalogue, no phone digits anywhere. The footer separates the hundred-year Bahujan lineage — Bhikhari Thakur, बिदेसिया, Padma Shri Ramchandra Manjhi — from the post-2000 commercial mutation, and links the orchestra-free-marriage movement in West Champaran.

docs/PRD.md §3 has the full position. It shaped the artwork, not just the copy.


Stack

Astro 5, static output, one npm dependency. Vanilla CSS, vanilla JS, no framework runtime, no database, no backend.

JS     13.5 KB gz      page total  26.8 KB gz
CSS     6.3 KB gz      fonts      261 KB (subset, font-display: swap)
HTML    7.0 KB gz      ← with the artwork already in it

Audio is a YouTube IFrame player. Nothing is hosted here.

The player survives navigation

This is why Astro rather than plain HTML: a radio whose music stops when you open another page is not a radio. It did not work for free —

  • transition:persist on an Astro component is silently dropped; it has to sit on the real root element inside the component file.
  • Persisting the node still isn't enough. Astro's default body swap moves persisted nodes into the new body, and moving an <iframe> reloads it — the node survived and the video went back to CUED at 0:00. src/scripts/swap.js replaces the swap with one that keeps the existing <body> and never detaches anything persisted.

Verified in real Chrome over CDP: / → /songs → /playlists with YouTube state staying 1 (PLAYING) and playback time advancing across both navigations.


Run it

npm install
npm run dev          # http://localhost:4321
Command
npm run build Static build into dist/
npm run tracks Rebuild the catalogue from the song seed (needs yt-dlp)
npm run revalidate Check all 59 YouTube IDs are still alive and embeddable
npm run fonts Re-download and re-subset the webfonts
npm run check:fonts Fail if any Devanagari character is missing from the subset

The catalogue

59 songs across five blocks, every ID resolved and verified — none guessed. scripts/build-tracks.mjs takes hand-written search queries, pulls five candidates each, scores them on artist-in-channel, title overlap (in both scripts — Bhojpuri uploads are titled in Devanagari and the first pass scored perfect matches at 0%), duration sanity and label channel, then dedupes, pre-flights embeddability and region, and verifies the cover art with a HEAD request.

Then a human reads all 59 rows, because that's the only real fix for the ~15% of searches that return a popular wrong song. Thirteen rows carry a hand-verified pinned ID.

29 candidates were dropped rather than guessed at — docs/rejected-songs.md records every one and the mechanism that caught it, including two "songs" that turned out to be lines inside other songs, and one whose real title the research had wrong.

src/data/songs.seed.js is the source of truth, not public/data/catalogue.json. The catalogue is generated and will be overwritten.

Fonts are subset to the glyphs the site renders

The Devanagari here is a closed corpus — a wordmark, some labels, 44 anchor lines, 59 song titles, all authored. After changing any Devanagari copy:

npm run build && npm run fonts && npm run build && npm run check:fonts

Miss it and new characters fall back to a system face mid-sentence.


Docs

docs/PRD.md The full spec — 19 sections
docs/HANDOVER.md What was built, what's verified, what isn't, and the bugs worth knowing about
docs/rejected-songs.md The 29 cuts and why
docs/verification/ CDP scripts and their raw output

Status

Built and verified in desktop Chrome. Not yet deployed. Still to do: a real-device pass on iOS Safari and Chrome Android (autoplay unlock, playsinline, lock-screen), and confirming the production URL in src/data/site.js.

One iOS limitation with no workaround: audio stops when the screen locks. That's an OS restriction on web audio in an iframe — Media Session supplies metadata but not background rights, and installing as a PWA doesn't change it. The footer says so plainly.


Audio plays through YouTube's embedded player. Nothing is hosted here, and all rights stay with the labels, composers and performers. Takedowns: raysanjeev19@gmail.com

About

आर्केस्ट्रा — a Bhojpuri stage-night radio. The songs an orchestra plays at a wedding in Bihar, in blocks, through the night. Astro, vanilla JS, YouTube-backed.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages