Video Utils¶
supervision.utils.video.VideoInfo
dataclass
¶
A class to store video information, including width, height, fps and total number of frames.
Attributes:
| Name | Type | Description |
|---|---|---|
width |
int
|
width of the video in pixels |
height |
int
|
height of the video in pixels |
fps |
float
|
frames per second of the video as a float. Common values include 23.976, 24.0, 25.0, 29.97, 30.0, 59.94, and 60.0. |
total_frames |
int | None
|
total number of frames in the video, default is None |
Examples:
import supervision as sv
video_info = sv.VideoInfo.from_video_path(video_path="<SOURCE_VIDEO_FILE>")
video_info
# VideoInfo(width=3840, height=2160, fps=25.0, total_frames=538)
video_info.resolution_wh
# (3840, 2160)
Source code in src/supervision/utils/video.py
Methods:¶
from_video_path(video_path: str) -> VideoInfo
classmethod
¶
Read video metadata from a file path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Path to the video file. |
required |
Returns:
| Type | Description |
|---|---|
VideoInfo
|
A |
Examples:
import supervision as sv
video_info = sv.VideoInfo.from_video_path(video_path="<SOURCE_VIDEO_FILE>")
# VideoInfo(width=3840, height=2160, fps=25.0, total_frames=538)
Source code in src/supervision/utils/video.py
supervision.utils.video.VideoSink
¶
Context manager that saves video frames to a file using OpenCV.
Attributes:
| Name | Type | Description |
|---|---|---|
target_path |
The path to the output file where the video will be saved. |
|
video_info |
Information about the video resolution, fps, and total frame count. |
|
codec |
FOURCC code for video format |
Example
import supervision as sv
video_info = sv.VideoInfo.from_video_path("<SOURCE_VIDEO_PATH>")
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
with sv.VideoSink(target_path="<TARGET_VIDEO_PATH>", video_info=video_info) as sink:
for frame in frames_generator:
sink.write_frame(frame=frame)
Source code in src/supervision/utils/video.py
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | |
Methods:¶
__enter__() -> VideoSink
¶
Open the underlying video writer for context-managed frame output.
Source code in src/supervision/utils/video.py
__exit__(exc_type: type[BaseException] | None, exc_value: BaseException | None, exc_traceback: TracebackType | None) -> None
¶
Release the underlying video writer when leaving the context.
Source code in src/supervision/utils/video.py
write_frame(frame: npt.NDArray[np.uint8]) -> None
¶
Writes a single video frame to the target video file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
NDArray[uint8]
|
The video frame to be written to the file. The frame must be in BGR color format. |
required |
Source code in src/supervision/utils/video.py
supervision.utils.video.FPSMonitor
¶
A class for monitoring frames per second (FPS) to benchmark latency.
Source code in src/supervision/utils/video.py
Attributes¶
fps: float
property
¶
Computes and returns the average FPS based on the stored time stamps.
Returns:
| Type | Description |
|---|---|
float
|
The average FPS across the recorded intervals. Returns 0.0 if fewer |
float
|
than two time stamps are stored. |
Methods:¶
__init__(sample_size: int = 30) -> None
¶
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
int
|
The maximum number of observations for latency benchmarking. |
30
|
Examples:
import supervision as sv
frames_generator = sv.get_video_frames_generator(
source_path="<SOURCE_FILE_PATH>")
fps_monitor = sv.FPSMonitor()
for frame in frames_generator:
# your processing code here
fps_monitor.tick()
fps = fps_monitor.fps
Source code in src/supervision/utils/video.py
reset() -> None
¶
supervision.utils.video.get_video_frames_generator(source_path: str, stride: int = 1, start: int = 0, end: int | None = None, iterative_seek: bool = False, prefetch: int = 0) -> Generator[npt.NDArray[np.uint8], None, None]
¶
Get a generator that yields the frames of the video.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
The path of the video file. |
required |
|
int
|
Indicates the interval at which frames are returned, skipping stride - 1 frames between each. |
1
|
|
int
|
Indicates the starting position from which video should generate frames |
0
|
|
int | None
|
Indicates the ending position at which video should stop generating frames. If None, video will be read to the end. |
None
|
|
bool
|
If True, the generator will seek to the
|
False
|
|
int
|
If > 0, decode frames in a background thread and buffer up to
this many frames in a bounded queue. Useful when the consumer (e.g.
CPU inference) is the bottleneck and can overlap with decode I/O.
This works best when the consumer releases the GIL during frame
processing (common for numpy/PyTorch/ONNX C-extension calls). Pure
Python per-frame consumers that hold the GIL (for example, heavy
Python loops, PIL usage, or pandas |
0
|
Returns:
| Type | Description |
|---|---|
None
|
A generator that yields the frames of the video. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
RuntimeError
|
If |
Note
For live camera streams, use cv2.VideoCapture with an integer device
index directly. get_video_frames_generator is designed for file-based
sources; cv2.VideoCapture must be released by the caller when done.
This requires OpenCV to be installed — the PyAV-based fallback used
when OpenCV is unavailable only supports file paths, not webcam device
indexes; passing an integer source to it always leaves the capture
closed (isOpened() returns False):
Examples:
import supervision as sv
for frame in sv.get_video_frames_generator(source_path="<SOURCE_VIDEO_PATH>"):
...
# Prefetch frames in a background thread to overlap I/O with CPU inference:
for frame in sv.get_video_frames_generator(
source_path="<SOURCE_VIDEO_PATH>", prefetch=8
):
...
Source code in src/supervision/utils/video.py
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | |
supervision.utils.video.process_video(source_path: str, target_path: str, callback: Callable[[npt.NDArray[np.uint8], int], npt.NDArray[np.uint8]], *, max_frames: int | None = None, prefetch: int = 32, writer_buffer: int = 32, show_progress: bool = False, progress_message: str = 'Processing video', preserve_audio: bool = False) -> None
¶
Process video frames asynchronously using a threaded pipeline.
This function orchestrates a three-stage pipeline to optimize video processing throughput:
- Reader thread: Continuously reads frames from the source video file and
enqueues them into a bounded queue (
frame_read_queue). The queue size is limited by theprefetchparameter to control memory usage. - Main thread (Processor): Dequeues frames from
frame_read_queue, applies the user-definedcallbackfunction to process each frame, then enqueues the processed frames into another bounded queue (frame_write_queue) for writing. The processing happens in the main thread, simplifying use of stateful objects without synchronization. - Writer thread: Dequeues processed frames from
frame_write_queueand writes them sequentially to the output video file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Path to the input video file. |
required |
|
str
|
Path where the processed video will be saved. |
required |
|
Callable[[NDArray[uint8], int], NDArray[uint8]]
|
Function called for each frame, accepting the frame as a numpy array and its zero-based index, returning the processed frame. |
required |
|
int | None
|
Optional maximum number of frames to process. If None, the entire video is processed (default). |
None
|
|
int
|
Maximum number of frames buffered by the reader thread. Controls memory use; default is 32. |
32
|
|
int
|
Maximum number of frames buffered before writing. Controls output buffer size; default is 32. |
32
|
|
bool
|
Whether to display a tqdm progress bar during processing. Default is False. |
False
|
|
str
|
Description shown in the progress bar. |
'Processing video'
|
|
bool
|
If True, copy the audio stream from |
False
|
Returns:
| Type | Description |
|---|---|
None
|
None |
Example
Source code in src/supervision/utils/video.py
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | |