> Source: https://nexusatlas.dev/guides/complete-footage — Nexus Atlas developer documentation (Guides). Converted from the HTML page; the page is canonical.

# Complete footage from a SAR drone shipped

A search-and-rescue drone streams video to a ground station over a link that drops packets. The pilot's view should give up late frames; the footage reviewed after the sortie should not. This guide sets up [backfill](https://nexusatlas.dev/docs/concepts/qos#backfill): the drone journals its video, the ground station asks for every hole, and the archive completes during the flight or after it.

> **What you need:** `[qos] enabled = true` on the drone and the ground station, the camera's stream classified as Video (RTP ports, an AF41 mark or a [[[qos.flow]]](https://nexusatlas.dev/docs/config#cfg-qos-flow) rule), disk for the journal on the drone and for the capture on the ground, and Python 3 where you convert captures.

## On the drone

```
[qos]
enabled = true

[qos.classes.Video]
retain = true                 # journal every Video packet

[qos.retain]
path = "/media/footage"       # removable storage; default is the state directory
max_bytes = "16 GiB"          # the ring: oldest segment goes first
max_secs = 86400

[storage]
at_rest = "on"                # journal sealed on disk
```

Run `atlasd config check`: it warns if the journal would be plaintext or if QoS is off. After a restart, `atlasd retain status` lists `Video` under retained classes and one line per stream with its sequence range.

## On the ground station

```
[qos]
enabled = true

[qos.retain]
path = "/srv/footage"         # captures land in <path>/atlas0.capture/
max_bytes = "64 GiB"          # a full capture stops growing; it never deletes

[storage]
at_rest = "on"
```

Nothing names the drone: any stream that arrives marked as journaled is captured and its holes are requested. The defaults wait 2 s before asking, so reordering and FEC repair first, and ask at most every 2 s. Set `backfill_max_kbps` on the drone if the backfill must leave fixed headroom on a shared link; without it, backfill takes only capacity no live class is using.

## Checking the archive

```
$ atlasd capture status
captures: 226.3 MiB of 65536.0 MiB under /srv/footage/atlas0.capture
requests sent 41 · answers 41 · backfill received 12972 · duplicates 0
  10.0.0.2        Video     stream 3d4c  100.00 %  187500 of 187500  missing 0  unrecoverable 0
```

Completeness is received packets over the stream's span, and the span includes the tail the live view never saw, because each answer carries the stream's highest sequence. `missing` is still requestable; `unrecoverable` is what the drone's journal no longer holds, because its ring turned over or a power cut took the last writes. On the dashboard the QoS tab shows the same figure in the Archive completeness card. After five minutes of a lossy link the archive completes about 14 s after the loss stops; a link cut mid-sortie completes once the path returns, and if the drone lands first, it completes when the drone is back on any link.

## Turning the capture into a file

```
$ atlasd capture export 10.0.0.2 Video --out sortie.atlcap
$ atlas_capture.py info sortie.atlcap
$ atlas_capture.py sdp sortie.atlcap -o sortie.sdp --port 5004
$ ffmpeg -protocol_whitelist file,rtp,udp -i sortie.sdp -c copy sortie.mkv &
$ atlas_capture.py replay sortie.atlcap --to 127.0.0.1:5004
```

`tools/atlas-capture/atlas_capture.py` runs beside the daemon, never in it, with the standard library only. `sdp` takes `--codec` to match the stream's payload; `replay` re-sends it in sequence order at the original pace, and `-c copy` keeps the encode untouched. `pcapng` writes the inner packets with their original timestamps for a packet tool instead. An export is plaintext: keep it on media you protect. When the review copy is safe, `atlasd retain clear` on the drone and `atlasd capture clear` on the ground free the space.

## Sizing the storage

The journal holds the stream at its own bitrate plus a little framing. At 6 Mbit/s that is about 2.7 GB an hour, so the 2 GiB default holds about 45 minutes; a 16 GiB card holds about six hours. Size the ground station's `max_bytes` for every drone it captures from.

## When the archive should be a better encode

Backfill completes the stream that was sent live, at the live bitrate. When the review copy should be a higher-quality encode than the live stream, record whole chunks on the drone instead, with the encoder writing files, and copy them over the tunnel with any TCP transfer, which lands in the Bulk lane by default. It costs the uplink twice and needs its own storage, and the chunks arrive whole or not at all.

## Boundaries

Frames are packets to Atlas: a frame lost on the drone before it reached the tunnel is not in the journal. A stream from an interconnect-mapped address is journaled but not backfilled. `POST /api/capture/export` answers up to 256 MiB; export larger captures with the CLI on the node.
