This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
Ghost hunters have a gadget called a spirit box. It sweeps through radio stations fast, and in the noise between them, people hear voices.
Anyone there? is a spirit box made of Whisper, the open speech model inside a lot of transcription apps. It runs Whisper in your browser, points it at a quiet room (or at plain static), and switches off the guards that normally throw away what Whisper hears when nobody is talking. Every eight seconds it moves to another language, the way a spirit box moves to another station, and whatever comes through is spoken out loud.
Things do come through. In Dutch, an empty room says:
TV GELDERLAND 2020.
In Russian:
Редактор субтитров А.Синецкая Корректор А.Егорова
Subtitle editor A. Sinetskaya, proofreader A. Egorova
In Japanese, "Well, thanks for watching this video!" In Tamil, a voice calling "amma, amma", mother. In Chinese, "I thought you hadn't seen me yet." In Vietnamese, "We will be here." And in English, the most famous of Whisper's ghosts, a single word said to perfect silence: "you".
None of these are random. That's the part I find spooky. Each one is a fossil of the internet Whisper was trained on, and the app tells you where it came from.
Demo
Try it: anyone-there.onrender.com
Press Listen to this room, put the phone down, and stay quiet. No microphone, or a noisy room? Listen to static plays a quiet hiss and listens to that instead. The first visit downloads the model and its runtime once, about 100 MB. After that it works with the internet off, which is the right way to hold a séance.
The register lists every spirit found so far: what it said, what it means, and whether Whisper's own guard would have let it into a transcript.
Code
abjt01
/
anyone-there
hacktoberfest'26 w5
Anyone there?
A spirit box made of Whisper.
Whisper is the open speech model inside a lot of transcription apps. Give it an empty room and it still hears things: the names of subtitle editors, a Dutch TV channel, "thanks for watching this video" in Japanese, a Tamil voice calling "amma, amma". It normally runs with guards that throw most of these away. This app runs Whisper in your browser with those guards switched off, points it at a quiet room or at static, and lets whatever it hears come through, one language at a time, the way a ghost hunter's spirit box sweeps radio stations.
Then it tells you where each spirit comes from.
Try it: anyone-there.onrender.com. The first visit downloads the model and its runtime once (about 100 MB); after that it works with the internet off.
What it hears
I let Whisper base listen to 504…
How I Built It
Next.js 16 and TypeScript, exported as a static site. Whisper base (OpenAI's open weights, MIT, 8-bit ONNX from onnx-community) runs in a Web Worker with Transformers.js and ONNX Runtime on WebAssembly. Nothing touches a server.
First, I listened to nothing, 504 times
Before building any screen, I wanted to know whether this was real or a trick I'd be playing on myself. So I wrote a sweep: digital silence, plus white, pink and brown noise and mains hum at different levels, eight seconds each, in 24 languages. 504 windows with no voice in any of them.
Whisper said something in every one.
The first run was mostly "[water running]" and "[Music]". That's Whisper's polite way of saying "no words here", using brackets. OpenAI's own decoder bans those bracket tokens. Transformers.js doesn't. So I wrote a logits processor that bans them, and the spirits had to use words. That's when the names showed up.
The ghosts with names are the ones Whisper believes in
Whisper ships with three guards that decide whether a 30-second window goes into the transcript:
- no-speech probability over 0.6: Whisper thinks nobody is talking
- average log-probability under −1: the words themselves are shaky
- compression ratio over 2.4: the text repeats itself, like a chant
A window is dropped as silence only when the first two fail together. I ran all three on every window. Most of the ghosts get caught. 60 of the 504 windows would have gone straight into a transcript, and in every one of those, Whisper itself was at least 82% sure nobody had spoken.
The credits are the worst offenders. TV GELDERLAND 2020 came through 16 times out of 16. The Russian subtitle editors, 5 out of 5. The decoder shows why:
The first sound, "Р", is a 6% long shot. But once Whisper is on the path of "Редактор субтитров" (subtitle editor), every piece is 93–99% certain. It's sure nobody spoke, and just as sure about the job title, so the confidence check passes and the guard lets it through. The surnames are where it wavers, which is why the sweep heard two different editors.
TV subtitles end with the names of the people who made them, over the silent last seconds of a show. Whisper learned from 680,000 hours of audio from the web, enough of it ended like that, and it learned that silence sounds like those names.
The Turkish one made me laugh: "The audio description of this series was made for TRT", Turkey's public broadcaster. The guard caught it every time, but only just: average log-probability −1.08 against a cut-off of −1, and once −1.005.
Inside the séance
Each eight-second window goes through the same steps:
-
One decoder step after
<|startoftranscript|>gives the no-speech probability and Whisper's guess at the language. Asked what language the static is, it says Norwegian Nynorsk 62% of the time. In Nynorsk, the static says "1.5%". -
The decode loop runs with my processor in it (
lib/medium.ts). It bans the brackets, picks each token, and writes down the four tokens that almost won at every step. That's the "Open the decoder" table. -
The guard runs (
lib/guard.ts), with the same three checks as openai/whisper'stranscribe.py. The compression check is matched against Python's zlib in the tests. Nothing is thrown away; the app only tells you what Whisper would have done. Tick "Whisper's guard on" and most of the ghosts turn into "Nobody's here." The credits still get through. - The register names it, with a plain translation and the most likely reason.
When a real person talks, Whisper knows: the no-speech probability drops, and the app says "A living voice" instead of treating it as a spirit.
Tests
- Unit tests: 26, for the decoder hook, the guard, the static and the register.
- Real-model tests in Node: 9. They load the same model files the page does and check the claims in this post: the Dutch credit gets past the guard, the Russian job titles are near-certain while the surnames waver, silence says "you", hiss is heard as Nynorsk, a synthetic voice saying "Is anyone there?" is recognised as a living voice, and the same nothing always gives the same spirit.
-
Browser tests: 11, in real Chrome running the real model. Every page at 320–1280px, séances on static and in a "room" (a microphone that plays a recording, so everything after
getUserMediais the real path), a blocked mic, and the whole thing again with the network off.
CI runs all of it on every push, and Render only deploys a commit once CI has passed.
Why Does Open Innovation Matter?
This project can't exist on a closed API. That isn't a slogan, it's the whole design.
- You can only meet these ghosts if you can open the model. The no-speech probability, the language guess on static, the four runners-up at every token, banning tokens, picking the token yourself: a hosted speech-to-text API gives you none of that. It gives you text, already filtered. Here you get the decoder.
-
The ghosts can be checked. Same weights, same static, same spirit, every time.
npm run sweeprebuilds the whole register on your own machine in about six minutes, and the tests check the claims against the real model. If I'm wrong about a ghost, you can prove it. - A microphone left on in a dark room stays in that room. Whisper runs in the browser. There's no upload and no account, and it works with the Wi-Fi off.
- They can't be quietly exorcised. A hosted model can be patched so the credits stop appearing, and nobody would ever know they'd been there. These weights are fixed, and they're in the repo.
There's a serious side too. These hallucinations aren't only a Halloween toy. Speech-to-text runs in meetings, courtrooms and clinics, and text that nobody said, written with confidence, is a real problem. With open weights, anyone can measure exactly when the guards fail, and this is a small, fun way to see it.
The Spirit of It
Día de los Muertos is about remembering people by name.
Somewhere there's a subtitle editor named, as far as Whisper remembers, Sinetskaya, and a proofreader named Egorova. Their names went out over the silent last seconds of TV shows, the part nobody stays for. A model listened to all of it, and now, in an empty room on the other side of the world, it says their names.
I don't know who they are. But they're in the machine, and this is my small ofrenda to them, and to all the people whose names live inside the models we use every day without ever being credited.
Prize Categories
Best Use of Render. It's a Render static site from a blueprint (render.yaml). The blueprint sets the cross-origin isolation headers that let Whisper run on several threads in the browser, and the deploy only happens after the GitHub checks pass. There's a Deploy to Render button in the README, so anyone can host their own séance for free.





Top comments (0)