How the Video Ingester works
Last updated: 10 August 2026
This page explains what the Video Ingester is, what problem it solves, and how the pieces fit together. Read it first — the rest of the documentation assumes you know the concepts introduced here.
What problem does it solve?
At a judo competition, cameras record the mats continuously. Software called the Video CutterV2 slices that continuous recording into one video file per contest (per fight). Those files then have to reach the FairReplay platform, where they are converted into a format that can be streamed, and linked to the correct contest in JudoManager or Judobase so that spectators, coaches and officials can find the right fight.
Getting the files from the recording PC to the platform is the job of the Video Ingester. It runs on a Windows PC at the venue and does three things:
- Notices new video files appearing on disk.
- Uploads them to cloud storage, in pieces, resuming and retrying as needed.
- Asks the platform to encode each uploaded file and attach it to the right contest.
Everything in between — queueing, ordering, retrying, reporting progress — exists to make those three steps reliable on a venue network that is often slow, shared and unstable.
Key terms
| Term | Meaning |
|---|---|
| Job | One video file making its way through the system. A job carries the file path plus all the metadata the encoder will need. |
| Watch folder | A folder on disk that the Ingester monitors. Any video file that appears there becomes a job. |
| Watcher | The role that finds new files and creates jobs. |
| Worker | The role that takes jobs off the queue and uploads/encodes them. |
| Contest code | The identifier that ties a video to one specific fight in JudoManager or Judobase. Without it, the platform does not know which contest the video belongs to. |
| Backend system | Which platform this Ingester talks to: JudoManager (JM) or Judobase (JB). |
| Partner | The federation or organisation that owns the event in JudoManager (for example Judo zveza Slovenije). Judobase does not use partners. |
| Payload | The JSON block stored with each job that holds the file path and encoder metadata. |
| Playable | The record on the FairReplay platform that represents the finished, streamable video. |
The two roles: Watcher and Worker
The Ingester has two independent roles. Both are toggled by the WATCHER and WORKER buttons at the top of the main window, and one running Ingester can be both at the same time — which is the normal setup.
- Watcher — monitors the watch folders and puts new jobs into the queue. It does not upload anything.
- Worker — takes jobs out of the queue, uploads the files and requests encoding. It does not look at watch folders.
Why are they separate?
Splitting the roles allows the workload to be spread across several PCs: one machine watches the folders and owns the queue, and several other machines act purely as workers, uploading in parallel over separate connections. This is supported by the software but is not the setup used in practice — in normal operation a single Ingester runs as both watcher and worker on one PC.
There must be exactly one watcher for a given set of watch folders. Two watchers pointed at the same folders would each create a job for the same file, and the file would be uploaded twice.
The blinking WORKER button
If the Worker role is switched off while jobs are sitting in the queue waiting to be processed, the WORKER button blinks amber and the taskbar icon flashes. This is a reminder that work is piling up and nothing is uploading it.
The job queue
Jobs live in a small SQLite database file called FileWatcherIngester.db, stored
next to the program in C:\FairReplay\Ingester. The watcher writes to it and workers
read from it.
Workers do not open the database file directly. Instead the queue is published as a small
web API on port 18472, and workers call it — at http://localhost:18472 by
default, meaning the same PC. That indirection is what makes splitting the roles across
PCs possible at all: a worker on another PC talks to the watcher over HTTP instead of
needing access to the database file.
Because the queue lives in a file on the PC, it survives restarts. Closing and reopening the Ingester does not lose queued jobs.
The life of a job
file appears in watch folder
│
▼
┌──────────┐ contest data missing ┌─────────────────────────────┐
│ pending │ ───────────────────────► │ waits for you to enter it │
└────┬─────┘ └─────────────────────────────┘
│ contest data present
▼
┌──────────┐
│ new │ waiting in the queue, ordered by priority
└────┬─────┘
│ a worker picks it up
▼
┌───────────┐
│ uploading │ file is sent to cloud storage in chunks
└────┬──────┘
│ all chunks sent and confirmed
▼
┌──────────┐
│ uploaded │ waiting for an encoding worker
└────┬─────┘
│ an encoding worker picks it up
▼
┌───────────────────────┐
│ creating encode job │ platform is asked to encode the video
└────┬──────────────────┘
│
▼
┌──────────┐
│ done │ finished — row disappears from the grid
└──────────┘
Three side branches exist:
- error — something went wrong during upload. The job stays visible so you can re-run it.
- failed — the request to create the encode job did not succeed.
- cancelled — you cancelled the job. The row disappears from the grid.
All job statuses
| Status | Meaning | Shown in the default grid? |
|---|---|---|
pending | Job exists but has no contest data yet. Nothing will happen until you supply it — select the row and click Contest Data, or right-click it and choose Set Contest Data. See Entering contest data by hand. | Yes |
new | Ready to be uploaded, waiting for a worker. | Yes |
uploading | A worker is transferring the file right now. The percentage is shown in the status column. | Yes |
uploaded | File is in cloud storage. Waiting for an encoding worker. | Yes |
creating encode job | The platform is being asked to encode the file. | Yes |
error | Upload failed. Row is coloured coral. | Yes |
failed | Encode request failed. Row is coloured coral. | Yes |
done | Finished successfully. | No — use Show all jobs |
cancelled | Cancelled by a user. | No — use Show all jobs |
The grid only shows jobs that still need attention. Finished and cancelled jobs are hidden so the list stays short during an event; click Show all jobs to see them.
Why upload and encoding are separate steps
Uploading a large video over a venue connection can take many minutes. Encoding, by contrast, is a request to the platform that returns quickly and is then processed in the cloud.
If the two were welded together, a single slow upload would block the encode requests
of files that had already finished uploading. They were therefore decoupled: one
worker loop handles uploads, and a separate pool of encoding workers (4 by default,
maximum 5) picks up anything in the uploaded state and requests encoding. This is
why you will see a job sit briefly at uploaded before moving on.
How files are found
The watcher notices new files in two independent ways, so that nothing is missed:
- Live file-system events. Windows notifies the Ingester the moment a file is created or changed in a watch folder.
- Periodic rescan. Every 15 seconds the Ingester also walks the watch folders (including sub-folders) from scratch. This catches files that arrived while the Ingester was closed, or that Windows failed to report.
You can also force a scan at any time with the Rescan folders button.
A file is turned into a job only if:
- its extension is in the Video file extensions list, and
- it is not locked by another program (the Video CutterV2 is still writing to it), and
- it has not already been processed.
"Already processed" is decided by asking the watcher which file paths it has seen before. The Ignore Canceled setting decides whether previously cancelled files count as already processed — see the settings reference.
Companion files
One optional file can sit next to a video file and change what happens to it:
| File | Purpose |
|---|---|
<video>.json | Written by the Video CutterV2. Carries the contest code, camera name, partner, backend system and other metadata, so the job can start uploading with no human input. |
The .json companion file is what makes automatic mode
possible. Its most important field is FinishedCutting: while it is false, the
Ingester deliberately skips the file, because the Video CutterV2 has not finished
writing it yet. Only once FinishedCutting is true is the job created.
If the companion file contains a contest code — and, for JudoManager, a partner — the
job is created directly as new and starts uploading. Otherwise it is created as
pending and waits for you to
enter the contest data by hand.
How the upload works
The file is not sent in one piece. The Ingester:
- Asks the platform for a set of pre-signed upload links, one per chunk.
- Sends the chunks, several at a time, to cloud storage.
- Tells the platform to finalise the upload, which reassembles the chunks.
Chunking is what makes uploads survivable on a poor connection: if one chunk fails, only that chunk is retried rather than the whole file. The chunk size is chosen from a short list — 5, 10, 25, 50, 100 or 150 MB, with 10 MB the default. Smaller chunks are more resilient on slow links, larger chunks are more efficient on fast ones.
Two settings control how hard the Ingester pushes the network:
- File chunk size — how big each piece is.
- Upload rate limit — a ceiling in Mbps on the total upload speed of the whole program. Setting a limit also automatically reduces how many chunks are sent in parallel, so that a limited Ingester does not open more connections than it can actually use.
Limiting the rate is useful when the same venue connection carries a live stream or scoring traffic that must not be starved.
What the platform receives
When the Ingester requests encoding it sends, among other things:
- where the uploaded file lives in storage,
- the contest code, so the platform can attach the video to the right fight,
- the camera name (Front, Side, Rear …), so several angles of the same fight can coexist,
- whether the video must be deinterlaced,
- whether to keep the original file in storage as well as the encoded version,
- an optional overlay image URL — a sponsor or broadcaster logo to be burned into the encoded video.
Registration
The Ingester is licensed software. An unregistered copy runs, but will process
only one job per program run; after that it refuses further uploads with a message
in the log. The window title also shows - UNREGISTERED.
See Registration and licensing for how to register.
Where things are on disk
| Path | What it is |
|---|---|
C:\FairReplay\Ingester\ | Default installation folder. |
C:\FairReplay\Ingester\FileWatcherIngester.exe | The program itself. |
C:\FairReplay\Ingester\settings.json | All settings. Written when you click Save settings. |
C:\FairReplay\Ingester\FileWatcherIngester.db | The job queue (SQLite). |
C:\FairReplay\Ingester\jwt.json | Licence token and machine key. |
C:\FairReplay\Ingester\IngestPartners.json | The list of JudoManager partners offered in the Contest Data form. |
C:\FairReplay\Ingester\logs\app\ | Application log, one file per day. |
C:\FairReplay\Ingester\logs\thread\ | Detailed upload/HTTP log, one file per day. |
Log files are rotated: they are archived once they exceed 100 MB, and 4 archives are kept. The Open logs button opens the log folder in Windows Explorer.