cardstream
Guide

Analyse your Whatnot or Fanatics Live stream

cardstream never logs in to Whatnot, Fanatics Live or any other marketplace. It watches the same video you are already sending them, on your own machine, and names every card that hits the table. Here is the whole path, from nothing to a live overlay — about fifteen minutes, once.

A computer near the camera

macOS, Linux or Windows. If you already run OBS on it, that machine is the right one — analysis happens locally, so nothing has to travel.

The video you already send

An OBS scene, a webcam, a capture card or an encoder. cardstream taps what you have; it does not ask you to restage the show.

A Ximilar API key

The one credential in the whole system, and it stays on your machine. No marketplace account, no password, no bot in your chat.

First

Get it running on its own

Before any of this touches your show, prove it works against your laptop webcam. Three commands.

01

Install it

The script builds a venv in ~/.cardstream, verifies the release wheel against its checksums, fetches the model weights and puts the commands on your PATH. Wheel, Docker and source installs are on the download page.

$ curl -fsSL https://raw.githubusercontent.com/Ximilar-com/cardstream/main/scripts/install.sh | sh
02

Add your key

Identification runs through Ximilar collectibles/v2 by default, or your own system in its place. XIMILAR_API_KEY is the only environment variable anything reads — put it in your shell profile so it survives a reboot on show night.

$ export XIMILAR_API_KEY=your-key
03

Hold a card up to your laptop

This opens the browser UI on your built-in webcam. Hold a card still for a beat: the overlay shows the state machine deciding, then the name, set and confidence, with the identify call’s wall time beside the match. That is the whole product — the rest of this page is only about where the pixels come from.

$ cardstream-web
# → http://127.0.0.1:8001
Then

Point it at your show

Pick one row. Which one depends on a single question — do you stream from a desktop or from a phone?

What you cannot do

Point cardstream at your public Whatnot or Fanatics playback page. There is no outbound stream URL for your own show, and scraping the player would add seconds of latency on top of the platform’s terms. Every route below taps your video upstream of the marketplace — which is exactly why cardstream needs no account, no password and no API key from them.

A
You stream from OBS on a desktop

The OBS virtual camera

Start here

OBS can present your composed scene to the operating system as an ordinary webcam. cardstream then opens it exactly like any other camera — no second encode, no extra load on your encoder and no ffmpeg to install.

  1. In OBS, click Start Virtual Camera in the controls dock.
  2. Run cardstream against it as a webcam index. Index 0 is usually your built-in camera, so the virtual one is normally 1 — try 0, 1, 2 until you see your scene.
$ cardstream-web --source 1

Try this once before a show rather than during one: on macOS the terminal needs camera permission, and if OpenCV cannot open the virtual device on your machine, route B works everywhere.

B
You stream from OBS and want the exact broadcast pixels

A second output from OBS

cardstream listens on your own machine and OBS pushes a copy to it. Whatnot or Fanatics keep receiving precisely what they received before — this is an extra target, never a redirect.

  1. Start the listener first; it waits for the push and reconnects on its own.
  2. OBS has only one Stream output, so send the copy from a second one: either the obs-multi-rtmp plugin, or Settings → Output → Recording → Custom Output (FFmpeg), type Output to URL, URL rtmp://127.0.0.1:1935/live, container flv — then press Start Recording.
  3. This route shells out to the system ffmpeg binary: brew install ffmpeg first.
$ cardstream-web --listen \
    --source rtmp://0.0.0.0:1935/live
C
You go live from a phone — most sellers

Its own camera on the table

A phone pushing straight to the app gives you nothing to tee. So stop chasing the outbound stream and give cardstream its own view of the same table: a second webcam overhead, or the camera’s HDMI out into a capture card.

  1. Point a webcam or capture card at the spot where you reveal.
  2. Run it on the machine next to that camera.
$ cardstream-web --source 0

It does not have to be your buyers’ angle. A tight, well-lit overhead shot identifies better than a compressed marketplace feed ever will.

D
You run an encoder, a switcher or an IP camera

Anything with a URL

rtsp://, rtmp:// and srt:// are pulled directly, plus ws:// JPEG feeds when your rig is homemade. Reconnects use capped backoff, so a studio link that drops mid-break comes back without you touching it.

  1. Give it the URL your encoder already publishes.
  2. The browser page becomes a passive viewer — analysis runs even with no browser open.
$ cardstream-web \
    --source rtsp://studio/stream1
Before you go live

Tune it for the show you are running

Defaults are honest, but a break is not a generic camera feed — you usually know what you are opening before you open it.

04

Tell it what you are breaking

A game or set prefill narrows the search: faster calls, better matches. One rule — always pass --alphabet when you pass --game, because a game prefill turns the endpoint’s own alphabet detection off and it then assumes latin, so a Japanese card would match its English print.

$ cardstream-web --source 1 \
    --game "Pokémon" --alphabet japanese --set-code M4
05

Change your mind mid-stream

When the next lot is a different game you do not restart anything: category, game, set code, alphabet and the result threshold are all editable in the browser settings dialog while the stream runs. Everything else — detector, gate, resolution — is read once at startup, so pick those now.

06

Keep the log, keep the port closed

--split-results gives every appearance its own row instead of merging repeats — a running list of what you showed, in the order you showed it, ready to reconcile against orders afterwards. Leave --host at its default 127.0.0.1: that process holds your key and the local UI is unauthenticated, so it should never be reachable from your LAN.

$ cardstream-web --source 1 --split-results

Then run your show. Detection, motion and the identity gate all run locally on your machine; the identification call fires once per card you put on the table — roughly a hundred in an hour, against the 54,000 frames that hour contains. The arithmetic is here.

If something is off

The six things that actually go wrong

The virtual camera is not in the list

Work through --source 0, 1, 2 in turn — the indices are whatever the OS hands out. On macOS, give your terminal camera access under System Settings → Privacy & Security. If OpenCV still will not open it, switch to route B.

“ffmpeg not found”

Only --listen and --ffmpeg shell out to the system binary. Install it (brew install ffmpeg) and rerun; the virtual-camera, webcam and plain-pull routes need nothing extra.

OBS will not let me add a second stream

That is an OBS limit, not a cardstream one — it has a single Stream output. The obs-multi-rtmp plugin adds real extra targets; the Custom Output (FFmpeg) recording path in route B works with stock OBS.

Cards are found but never matched

Almost always resolution or motion. The card number has to be legible in the frame you send: keep OBS at 1080p, hold the reveal still for a beat, and only then loosen --result-threshold (default 0.9 — higher keeps weaker matches, 1.0 keeps everything).

The same card is identified twice

The identity gate scored the two views below --similarity-threshold (default 0.85) and called it a new card. Lower it a little. If you set a card down and pick it back up, raise --forget-after instead — after 2 seconds away, a card is treated as fresh by design.

Nothing is detected at all

Run with --show-detection to draw the box: detection always runs, it is just not drawn by default. No box means the card is too small or too fast in frame; a box with no match sends you to the row above.

Still stuck? The README documents every flag, and the docs hub groups them by what you are trying to do.

Open source. Self-hosted. Your stream, your stack.

No platform in the middle, no seat licence: connect the Ximilar API or your own identification system, and cardstream calls it once per distinct card instead of once per frame. Whether you're breaking on Whatnot, running a Fanatics Live-style show, or streaming your own live commerce setup, run cardstream tonight on the hardware you already have.