Stoatworks Labs

BirdDog PLAY Flasher (beta)

A factory image onto a decoder in recovery mode, over USB

In developmentRuns in a browser tab

The other case: a decoder that has stopped answering.

The Patcher assumes a unit whose web page still loads. This is for one that doesn't: a PLAY held in Rockchip recovery mode, flashed from a browser tab over USB, with the factory image read off your own disk. It can also park a firmware package inside that image on the way, so the unit comes up already patched instead of needing a second pass.

It's a beta, and the page says why up front: no injected package has yet been watched to install on first boot. The parsers, the partition table and the filesystem injection are tested against genuine vendor files, and the USB half has met a real PLAY, with the loader push, the re-enumeration wait after it and the read-back verification each corrected against what the device actually did. The Patcher, the firmware patches and the replacement operating systems are all on the BirdDog PLAY page. Not affiliated with, endorsed by or supported by BirdDog.

BirdDog PLAY Flasher (beta) — A factory image onto a decoder in recovery mode, over USB
A genuine factory image and an update package chosen: the nine-entry GPT read off the 2.4 GB file in slices, the package parked for first boot, and nothing connected yet, because everything after that needs a PLAY in recovery mode on the other end of a cable.

What it does

01

The whole device, put back

Bootloader, u-boot, trust, kernel, device tree, rootfs and the partition table, written from a factory image you supply. This is the brick-recovery path: it doesn't need the unit to boot, to hold an address, or to serve its web page.

02

A package that installs itself

Optionally, the .fw the Patcher built goes into the image on the way through, and a one-shot service hands it to the decoder's own updater on first boot, so the unit arrives patched. It marks itself done before installing rather than after, so a package that kills the box can't reinstall itself on every boot.

03

It costs the filesystem nothing

The rootfs partition is 3.5 GB and the image inside it is 2.2 GB, so there's over a gigabyte at the end that nothing ever grows into. The package is parked there as raw bytes. The three small files that call it back are added to a plain ext2 filesystem (no journal, no extents, no checksums), which is what makes writing them from JavaScript defensible rather than reckless.

04

Nothing is uploaded, and no key is involved

Your image never leaves the machine: it's read through the file picker, parsed in the tab and pushed straight down the USB cable. Even the loader that gets sent to the device first is extracted from your own file at run time. There's no vendor key anywhere in this, which is the only reason it can be a public page at all.

What to check before a show

  1. 01

    No injected package has been watched to install yet

    That's the beta, and it's the first thing on the page. What's proven is the image parsers, an independent check of both partition-table checksums, a write plan that provably overlaps nothing, and a filesystem check that accepts the patched 2.4 GB rootfs and reads the injected files back. Since 15 August 2026 that's included the USB half against a real PLAY, where the loader push, the re-enumeration wait after it and the read-back verification were each corrected by what the device did. What isn't proven is the first-boot install of an injected package: nothing has yet been seen to boot and apply one. Don't learn that on a unit you need on Monday.

  2. 02

    You supply the firmware image

    Nothing of BirdDog's is hosted here or bundled with the page. It's a tool for a file you already have. Getting the right factory image for your unit is on you, and flashing the wrong one is how a working decoder becomes an interesting paperweight.

  3. 03

    The recovery button is inside the headphone socket

    Not on the outside of the case. A straightened paperclip or a SIM tool pushed gently to the bottom of the 3.5 mm socket finds it. Hold it down, apply power, keep holding for a few seconds, then connect USB. If the unit boots normally instead, the button wasn't held far enough down or long enough.

  4. 04

    Windows needs a driver swap, and it needs Chromium

    WebUSB can only reach a device bound to WinUSB, and Rockchip's own driver claims the unit first, so Windows needs Zadig to rebind it. macOS needs nothing; Linux needs a udev rule. And this is WebUSB, so it's Chrome, Edge or another Chromium browser. Firefox and Safari don't implement it, and the page says so rather than failing quietly.

  5. 05

    A working unit doesn't need any of this

    If the decoder still serves its web page, upload the .fw through the System tab and be done. This exists for the unit that won't boot, won't take an update, or needs putting back to a known state.

Run your own copy

BirdDog PLAY Flasher (beta) is also published as a Docker image, ghcr.io/stoatworks-labs/birddog-play-flasher, serving the same files as the hosted copy. On a laptop or a box in the rack it keeps working when the venue's internet doesn't.

Docker

docker run -d --name birddog-play-flasher --restart unless-stopped -p 8539:80 ghcr.io/stoatworks-labs/birddog-play-flasher:latest

Then it's at http://localhost:8539/. The repo's docker-compose.yml does the same with docker compose up -d.

Unraid

Search Community Applications for birddog-play-flasher and install it. The template sets the port to 8539 for you.

Self-hosting the web tools, and which ones you can