Here's a little javascript web app I'm working on: Weird Waves, a fake online radio station for horror audiobooks and radio plays!
I dunno how far off the final app is. The rest of this post's just an explanation of how it works.
The idea
What's a fake online radio station
? I mean a simple web app that plays audio shows every hour on the hour—so simple it can run on static hosting (no need for server-side scripts or a database). You go to the site, you click a button labelled "tune in", and it starts playing the current show in the schedule. It starts from the point in the show when you arrive, not the beginning of the show, and it plays the same show no matter what timezone you're in. For instance:
- You arrive at 10:15. The app starts playing the 10 o'clock show, from 15 minutes in.
- You arrive 10:45. The app starts playing the intermission track.
- You arrive at 10:59 and let the clock tick past 11:00. First you hear the intermission track, then at 11 o'clock the next show starts.
What about those horror audiobooks and radio plays
? Here's the kinda stuff I mean:
- episodes of old horror radio anthologies like Quiet, Please, if they're public domain (or if they might as well be)
- other radio series dedicated to the public domain, like Seeing Ear Theatre or Mind Webs (only some/a few of these episodes fit into “horror”, but there's a bunch of sci-fi ones too)
- serial or anthology horror podcast episodes released under CC licenses, like The Magnus Archives, The Silt Verses, or Pseudopod
- horror audiobooks off places like LibriVox (mixed quality, but some of them are decent), which have readings of older (mostly 19th/early 20th-century) novels and short stories
- hopefully, book readings from people's youtube channels, if they're okay with it (again, mixed quality, but there's e.g. some real good dry readings of Thomas Ligotti's short stories)
How it works
The schedules
The app works off a weekly schedule that's split into two blocks:
-
Weekday, a block of 4 shows that runs on repeat every day from Monday to Friday. This block shifts by 1 show every midnight (e.g. if you listen at 10 p.m. on Monday you'll hear one show, and if you listen at 10 p.m. on Tuesday you'll hear the next show, and so on).
-
Weekend, a block of 6 shows that runs on repeat every Saturday and Sunday. This runs the same on both days.
The blocks can actually be any number of shows long, but it's neater if they divide evenly into 24 (for 24 hours). Those numbers are 1, 2, 3, 4, 6, 8, 12, or 24 shows per block.
Each schedule is a .json
file stored separate from the script that contains some info about the schedule, plus the lists of shows for each block:
{
"info": {
"title": "Regular Test Schedule",
"description": "This is a test schedule loaded from a separate file. It plays a mix of episodes from the 1940s weird fiction/sci-fi/horror radio anthology, <cite>Quiet, Please</cite>.",
"intermission": "test-intermission.mp3"
},
"weekday": [
{
"file": "QP-001.mp3",
"id": "qp-001"
},
{
"file": "QP-002.mp3",
"id": "qp-002"
},
{
"file": "QP-004.mp3",
"id": "qp-004"
}
],
"weekend": [
{
"file": "QP-006.mp3",
"id": "qp-006"
}
]
}
The script fetches schedules from the server using their filenames. Each schedule file has a name in this format: schedule-YYYY-MM-DD.json
, where YYYY-MM-DD
is the date of that week's Monday (in the station's timezone). If the script fails to fetch the schedule then it goes with a default schedule written into the script file itself.
Here's what schedule.info
is used for:
.title
- Each schedule gets a name that goes in a heading near the top of the app page. If a schedule's got a theme (e.g. underground horror, cosmic horror, dream horror) then that theme can go in the title somehow.
.description
- Each schedule gets a single paragraph of description. In future I might change this to allow multiple paragraphs.
.intermission
- Each week has its own intermission track. The schedule provides the filename and the script plays that file between shows.
schedule.weekday
and schedule.weekend
list the shows in each block. For each show, they have the filename and an ID that points to its metadata, which is written on the app page. For instance, the ID qp-001
points to this metadata:
<li id="qp-001">
<h5 class="archive-show-title">Nothing Behind the Door</h5>
<dl class="archive-show-info">
<dt>Episode</dt>
<dd><a href="https://www.quietplease.org/episodes/nothing-behind-the-door-1.html">Quiet, Please #1</a></dd>
<dt>Blurb</dt>
<dd>Bank robbers try to hide the money in a mountain shed that contains nothing. Literally nothing.</dd>
<dt>Notes</dt>
<dd>none</dd>
<dt>Airdate</dt>
<dd><time>1947-06-08</time></dd>
</dl>
</li>
Which looks (kinda) like this on the page:
-
Nothing Behind the Door
- Episode
- Quiet, Please #1
- Blurb
- Bank robbers try to hide the money in a mountain shed that contains nothing. Literally nothing.
- Notes
- none
- Airdate
Since the metadata's gonna be on the page anyway, I don't need to put show metadata in the schedule file, just a pointer to the metadata on the page. That keeps schedule files small and simple.
The player
Once the player's got the schedule (weekly or default), it can start playing audio. It starts playing when you tune in. Like I explained up above, it follows a set schedule with shows starting every hour on the hour, so if you arrive at X minutes past the hour then the app starts playing the track X minutes in.
There's a little issue right now where if you and arrive in the intermission then the player might play the final seconds of the last show before starting the intermission, but that's not a big deal.
Finally, there's a few controls: a mute/unmute button and a volume slider.
The rest of the app
The rest of the app's gonna have different sections in tabs on the same page (putting everything on one page means the audio won't get broken by navigating between pages):
- Forecast: lists of all the shows in the current schedule, split by whether they're in the weekday or weekend block, plus tables of the upcoming shows hour by hour.
- Archive: lists of all the metadata for every show and series that's been broadcast (or has been added on the current schedule): descriptions, sources, content notes, license info, that kinda stuff. The app pulls this to build the info for the currently-playing show and the forecast lists.
- About, News, and FAQ: pretty much what they sound like.
- a few other minor things
What next?
The player's pretty much done, I think. It's ~11 KB of javascript, including explanatory comments, and I think all the moving parts are working. There's one thing I need to test with the forecast tables (at the end of each day in your timezone, the now-empty table should be removed from the page).
Here's the to-do list:
- (maybe) allow more than 1 paragraph in schedule descriptions
- (maybe) add fade-in/out on intermission audio
- listen to a more podcast episodes, radio plays, and audiobooks
- update the content notes on the shows I've already added
- set up all the other sections besides the Forecast and Archive
- add styles, icons, and a proper favicon
- write/rewrite the text in tune with the radio horror vibe
It's an alpha/proof of concept right now! And I'm working on it when I have the time, so I dunno exactly when it'll be ready.
Return to top