Metadata-Version: 2.4
Name: vidstats
Version: 0.1.2
Summary: Extract per-frame colour and luminosity metrics from video via ffprobe signalstats.
Project-URL: Repository, https://github.com/roaldarbol/vidstats
Project-URL: Issues, https://github.com/roaldarbol/vidstats/issues
Author-email: Mikkel Roald-Arbøl <vidstats.ez7zw@passmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: colour,ffprobe,luminosity,signalstats,video
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.10
Requires-Dist: polars>=0.20
Requires-Dist: typer>=0.9
Requires-Dist: typing-extensions>=4.0
Description-Content-Type: text/markdown

# vidstats

Extract per-frame colour and luminosity metrics from video using
[ffprobe's `signalstats` filter](https://ffmpeg.org/ffmpeg-filters.html#signalstats).
Output goes to Parquet, CSV, IPC/Feather, or NDJSON.

Designed for research pipelines that need a fast, dependency-light way to turn
a video into a tabular time series — for example, non-contact cardiac monitoring
in animals via colour/motion video analysis.

## Installation

**pixi** (recommended — pulls in ffmpeg automatically):

```bash
pixi global install vidstats
```

**uv** (global install):

```bash
uv tool install vidstats
```

**conda**:

```bash
conda install -c conda-forge vidstats
```

**pip** (requires ffmpeg on PATH separately):

```bash
pip install vidstats
```

## Usage

```bash
# Extract all metrics → Parquet
vidstats input.mp4 output.parquet

# Extract only luminance and saturation averages → CSV
vidstats input.mp4 output.csv --metrics YAVG,SATAVG

# Include both frame number and timestamp in seconds
vidstats input.mp4 output.parquet --timestamps both

# Override FPS when stream metadata is missing or wrong
vidstats input.mp4 output.parquet --timestamps both --fps 30

# Apply a crop region (X Y W H) before extraction
vidstats input.mp4 output.parquet --crop "10 20 180 180"

# Force format regardless of extension
vidstats input.mp4 output.dat --format csv

# Disable hardware acceleration
vidstats input.mp4 output.parquet --no-hwaccel

# List all available metric names and their output column names
vidstats --list-metrics
```


## Python API

vidstats can also be used directly from Python. The simplest path is the
`extract()` convenience function:

```python
import vidstats

df = vidstats.extract("input.mp4")
```

`df` is a Polars DataFrame with the same schema as the CLI output. Optional
arguments mirror the CLI:

```python
df = vidstats.extract(
    "input.mp4",
    metrics=["YAVG", "SATAVG", "HUEMED"],  # default: all metrics
    crop=(10, 20, 180, 180),               # (x, y, w, h) in pixels
    include_time=True,                     # adds time_s column
    fps=25.0,                              # override FPS for time_s
    hwaccel="cuda",                        # hardware decode acceleration
)
```

Write the result with any Polars method:

```python
df.write_parquet("output.parquet")
df.write_csv("output.csv")
```

## Supported output formats

| Extension(s)                   | Format    |
|--------------------------------|-----------|
| `.parquet`                     | Parquet   |
| `.csv`                         | CSV       |
| `.tsv`                         | TSV       |
| `.ipc`, `.arrow`, `.feather`   | Arrow IPC |
| `.ndjson`, `.jsonl`            | NDJSON    |

## Available metrics

All 25 `signalstats` metrics are extracted by default. Run
`vidstats --list-metrics` for the full table of ffprobe names, output column
names, and descriptions. They cover:

- **Luminance**: `YMIN`, `YLOW`, `YAVG`, `YHIGH`, `YMAX`
- **Cb chrominance (U)**: same set of five
- **Cr chrominance (V)**: same set of five
- **Saturation**: `SATMIN`, `SATLOW`, `SATAVG`, `SATHIGH`, `SATMAX`
- **Hue**: `HUEMED`, `HUEAVG`
- **Quality flags**: `TOUT`, `VREP`, `BRNG`

The `--metrics` flag accepts ffprobe names (e.g. `YAVG,SATAVG`).
Output columns use descriptive snake_case names (e.g. `luminance_mean`,
`saturation_mean`) — see `--list-metrics` for the full mapping.

## Output schema

| Column    | Type    | Condition                          |
|-----------|---------|------------------------------------|
| `frame`   | UInt32  | always                             |
| `time_s`  | Float64 | `--timestamps seconds` or `both`   |
| metrics…  | Float32 | selected metrics                   |

`time_s` is computed as `frame / fps`. FPS is read from stream metadata
automatically; use `--fps` to override it or supply it when metadata is absent.

## Hardware acceleration

vidstats auto-detects CUDA and passes `-hwaccel cuda` to ffprobe if available.
This accelerates the **decode** stage only — `signalstats` itself always runs
on CPU. For small (e.g. 200×200) videos the gain is negligible, but the
detection is there for larger inputs. Suppress with `--no-hwaccel`.

No special CUDA packages or drivers are required beyond what you already have.
vidstats uses ffprobe's built-in NVDEC hardware decoding, which talks directly
to the NVIDIA driver on your system — there is no `cudatoolkit`, no
`pytorch-cuda`, and no GPU-specific installation step.

## License

MIT