# DJI SRT Telemetry Formats
This document describes the different SRT telemetry formats used by different DJI drone models.
## Format Types
### Format 1: Bracketed Key-Value Pairs
Used by: DJI Mini 3 Pro, DJI Mini 4 Pro, some newer models
```
[latitude: 59.302335] [longitude: 18.203059] [rel_alt: 1.300 abs_alt: 132.860] [iso : 2700] [shutter : 1/30.0] [fnum : 170]
```
**Fields:**
- `latitude`: GPS latitude in decimal degrees
- `longitude`: GPS longitude in decimal degrees
- `rel_alt`: Relative altitude from takeoff point (meters)
- `abs_alt`: Absolute altitude above sea level (meters)
- `iso`: Camera ISO value
- `shutter`: Shutter speed (e.g., 1/30.0)
- `fnum`: F-number × 100 (170 = f/1.7)
### Format 2: GPS Function Format
Used by: DJI Mavic Pro, DJI Phantom 4, older models
```
GPS(39.906217,116.391305,69.800) BAROMETER(91.2)
HOME(39.906206,116.391400) D=5.2m H=1.5m
```
**Fields:**
- `GPS(lat,lon,alt)`: GPS coordinates and altitude
- `BAROMETER(value)`: Barometric pressure reading
- `HOME(lat,lon)`: Home point coordinates
- `D`: Distance from home point
- `H`: Height above home point
> The HOME point is parsed only when `--extract-home` is passed (it is the
> operator's launch location). When extracted it is subject to `--redact`.
### Format 2b: Legacy-with-Unit (Matrice 300 lineage)
Used by: DJI Matrice 300 RTK and adjacent enterprise models.
```
GPS(36.6146,-6.1120,0.0M) BAROMETER:0.3M
```
Identical to Format 2 except the altitude inside the GPS tuple carries a
unit suffix (`M`) and BAROMETER uses a colon notation rather than
parentheses. The parser tolerates the suffix via an optional
`[A-Za-z]*` group on the altitude capture; latitude and longitude are
extracted as for Format 2.
### Format 2c: P4 RTK Compact Single-Line
Used by: DJI Phantom 4 RTK, Phantom 4 Pro, and likely the Matrice
350 RTK / Matrice 30 enterprise lineage.
```
F/5.6, SS 400, ISO 100, EV 0, GPS (-58.851745, -34.237922, 15),
HOME (-58.847509, -34.232707, -57.98m), D 698.70m, H 85.80m,
H.S 0.00m/s, V.S 0.00m/s, F.PRY (2.7°, -7.0°, 110.1°),
G.PRY (-24.4°, 0.0°, 110.4°)
```
**Fields parsed today:**
- `GPS (lat, lon, alt)` — note the space before `(` and integer altitude
- `F/N` → camera fnum (free-standing, not `[fnum:…]`)
- `SS N` → camera shutter
- `ISO N` → camera iso
- `EV N` → camera ev
**Fields recognised but not yet decoded** (open follow-up):
`HOME (…)`, `D Nm`, `H Nm`, `H.S Nm/s`, `V.S Nm/s`, `F.PRY (p, r, y)`,
`G.PRY (p, r, y)`. These tokens are documented for future work; the
parser currently extracts GPS + camera and ignores the rest.
### Format 3: Comprehensive Format
Used by: DJI Mavic 3, DJI Air 2S
```
SrtCnt : 1, DiffTime : 33ms
2024-01-15 14:30:22,123
[iso : 100] [shutter : 1/1000] [fnum : 280] [ev : 0] [ct : 5500] [color_md : default] [focal_len : 240] [latitude: 59.302335] [longitude: 18.203059] [rel_alt: 10.200 abs_alt: 142.760]
```
**Additional Fields:**
- `SrtCnt`: Frame counter
- `DiffTime`: Time difference from previous frame
- `ev`: Exposure compensation
- `ct`: Color temperature
- `color_md`: Color mode
- `focal_len`: Focal length × 10 (240 = 24mm)
### Format 3b: Modern HTML Bracket (FrameCnt + decimal units)
Used by: DJI Mini 5 Pro, DJI Avata 360, DJI Neo 2, DJI Air 3S
Current models keep the HTML-wrapped bracket structure of Format 3 but change
two things: the counter is `FrameCnt` (not `SrtCnt`), and the aperture and
focal length are written as **literal decimals** rather than the legacy
×100 / ×10 integer encodings.
```
FrameCnt: 1, DiffTime: 40ms
2026-05-27 13:14:22.911
[iso: 200] [shutter: 1/6400.0] [fnum: 1.8] [ev: -0.7] [color_md: dlog_m] [focal_len: 24.00] [latitude: 53.365108] [longitude: 6.460719] [rel_alt: 6.000 abs_alt: -122.769] [ct: 5263]
```
**Notes:**
- `fnum: 1.8` is the literal f-number (f/1.8), not `180`.
- `focal_len: 24.00` is the literal focal length in mm, not `240`.
- The Avata 360 variant adds a `FrameId`, a `dzoom_ratio`, gimbal
(`gb_yaw`/`gb_pitch`/`gb_roll`), and a block of stabilization /
post-processing fields (`eis`, `shift x/y`, `pp_*`). These are ignored by
the parser but are valid telemetry-line content.
- Avata 360 footage is delivered as `.OSV` (360 video) plus a `.LRF` low-res
proxy instead of `.MP4`; both are MP4-family containers and are processed
like any other video. See [troubleshooting](troubleshooting.md).
- The Air 3S variant omits the `pp_*` stabilization block but is the first
observed fixture to report `color_md: hlg` (HLG color mode, alongside the
usual `default`/`dlog_m`). Its MP4 also carries DJI's proprietary
`djmd`/`dbgi` data streams, dropped on MP4 mux and round-tripped on MKV.
- Detected as the `html_extended` format family.
## Camera Settings Interpretation
### ISO Values
- Direct value (e.g., 100, 200, 400, 800, 1600, 3200)
### Shutter Speed
- Fractional format: `1/1000`, `1/500`, `1/250`
- Decimal format: `1/1000.0`
- Long exposure: `2.0` (2 seconds)
### F-Number (Aperture)
- Legacy encoding: integer × 100 (`170` = f/1.7, `280` = f/2.8, `400` = f/4.0)
- Modern encoding (Format 3b): literal decimal (`1.8` = f/1.8, `1.9` = f/1.9)
- The parser stores the value verbatim and does not convert between the two.
### Focal Length
- Legacy encoding: integer × 10 (`240` = 24mm, `350` = 35mm, `500` = 50mm)
- Modern encoding (Format 3b): literal decimal mm (`24.00` = 24mm)
## Camera Footprint Export — Relevant Fields
The `convert geojson/kml --footprint` command uses three SRT fields to project
ground-footprint polygons. Not all formats carry all three:
| Field | Formats that carry it | Role in footprint export |
|-------|-----------------------|--------------------------|
| `rel_alt` | Format 1, Format 3, Format 3b | Height above ground (AGL). Preferred over `abs_alt` subtraction. |
| `focal_len` | Format 3, Format 3b | 35mm-equivalent focal length. Determines field of view. Written as integer × 10 in Format 3 (`240` = 24 mm) or literal decimal in Format 3b (`24.00` = 24 mm). Overrides the `--model` table when present. |
| `gb_yaw`, `gb_pitch` | Format 3b — **Avata 360 variant only** | Gimbal yaw rotates the footprint rectangle to match where the lens points; gimbal pitch gates out strongly oblique frames (>~30° off nadir). Other Format 3b models and all earlier formats do not carry these fields — nadir is assumed and heading falls back to course over ground. |
When none of these fields are present (e.g., Format 2 / Format 2b / Format 2c),
footprints are still generated using `abs_alt` for AGL estimation, the `--model`
FOV table (or the generic wide fallback), and course-over-ground for orientation.
## GPS Coordinate Formats
### Decimal Degrees
- Standard format: `59.302335`
- Range: -90 to 90 for latitude, -180 to 180 for longitude
- Precision: Usually 6-7 decimal places
### Altitude
- Relative altitude: Height from takeoff point
- Absolute altitude: Height above sea level
- Units: Meters
- Can be negative (below takeoff point or sea level)
## Timestamp Formats
### SRT Standard
```
00:00:00,000 --> 00:00:00,033
```
- Hours:Minutes:Seconds,Milliseconds
- Arrow indicates duration of subtitle display
### Extended Format
```
2024-01-15 14:30:22,123
```
- Full date and time for precise temporal reference
## Adding Support for New Formats
To add support for a new DJI model's SRT format:
1. **Identify the Pattern**: Open SRT files and identify the telemetry pattern
2. **Create Regex Patterns**: Design regex to extract each field
3. **Update Parser**: Add new parsing logic to `parse_dji_srt()` method
4. **Test**: Ensure backward compatibility with existing formats
### Example Parser Addition
```python
# New format: |LAT:59.302335|LON:18.203059|ALT:132.86|
new_format_match = re.search(r'\|LAT:([+-]?\d+\.?\d*)\|LON:([+-]?\d+\.?\d*)\|ALT:([+-]?\d+\.?\d*)\|', telemetry_line)
if new_format_match:
lat = float(new_format_match.group(1))
lon = float(new_format_match.group(2))
alt = float(new_format_match.group(3))
telemetry_data['gps_coords'].append((lat, lon))
telemetry_data['altitudes'].append(alt)
```
## Known Model-Format Mappings
| Model | Format Type | Notes |
|-------|------------|-------|
| DJI Mini 3 Pro | Format 1 | Bracketed key-value pairs |
| DJI Mini 4 Pro | Format 1 | Bracketed key-value pairs |
| DJI Mavic 3 | Format 3 | Comprehensive with HTML tags |
| DJI Air 2S | Format 3 | Comprehensive with HTML tags |
| DJI Air 3 | Format 3 | Comprehensive with HTML tags |
| DJI Mini 5 Pro | Format 3b | FrameCnt + decimal fnum/focal_len |
| DJI Avata 360 | Format 3b | FrameCnt + decimal units; `.OSV`/`.LRF` video, `pp_*` stabilization fields |
| DJI Neo 2 | Format 3b | FrameCnt + decimal units; `pp_*` stabilization fields; MP4 carries `djmd`/`dbgi` streams; audio recorded to a **separate same-basename `.m4a`** (see `--audio-sidecar`) |
| DJI Air 3S | Format 3b | FrameCnt + decimal units; `color_md: hlg`; MP4 carries `djmd`/`dbgi` streams |
| DJI Mavic Pro | Format 2 | GPS function format |
| DJI Phantom 4 | Format 2 | GPS function format |
| DJI Avata 2 | Format 2 | GPS function format with BAROMETER data |
| DJI Matrice 300 RTK | Format 2b | Legacy-with-unit (`0.0M` altitude) |
| DJI Phantom 4 RTK / P4P | Format 2c | P4 RTK compact single-line |
| DJI Mavic Air 2 | Format 1 | Bracketed key-value pairs |
| DJI FPV | Format 1 | May include additional flight data |
## Special Considerations
### Frame Rate
- SRT timestamps typically match video frame rate
- Common rates: 23.976, 24, 25, 29.97, 30, 50, 59.94, 60 fps
### Coordinate Systems
- Most DJI drones use WGS84 datum
- Coordinates are typically in decimal degrees
- Altitude reference may vary (MSL vs AGL)
### Missing Data
- GPS may not be available immediately after takeoff
- Indoor flights won't have GPS data
- Some fields may be empty or zero