---
title: video
---

<div class="python-reference">
<a id="fastvideo.eval.io.video-functions"></a>
<a id="fastvideo.eval.io.video"></a>

<h2 id="fastvideo.eval.io.video.load_video"><code>fastvideo.eval.io.video.load_video</code></h2>
<pre class="doc-signature"><code>load_video(source: str | torch.Tensor | list, **kwargs) -&gt; torch.Tensor</code></pre>
<p>Load a video as a <code>(T, C, H, W)</code> float32 tensor in <code>[0, 1]</code>.</p>
<p>Supported <em>source</em> types:</p>
<ul>
<li><strong>str / Path</strong> – path to <code>.mp4</code> / <code>.avi</code> / <code>.gif</code> file, or a
  directory of frame images (sorted alphabetically).</li>
<li><strong>torch.Tensor</strong> – returned as-is after shape validation.</li>
<li><strong>list[PIL.Image]</strong> – stacked into a tensor.</li>
</ul>
<details><summary>Source</summary><pre><code>def load_video(source: str | torch.Tensor | list, **kwargs) -&gt; torch.Tensor:
    &quot;&quot;&quot;Load a video as a ``(T, C, H, W)`` float32 tensor in ``&#91;0, 1&#93;``.

    Supported *source* types:

    * **str / Path** – path to ``.mp4`` / ``.avi`` / ``.gif`` file, or a
      directory of frame images (sorted alphabetically).
    * **torch.Tensor** – returned as-is after shape validation.
    * **list&#91;PIL.Image&#93;** – stacked into a tensor.
    &quot;&quot;&quot;
    if isinstance(source, torch.Tensor):
        if source.ndim != 4:
            raise ValueError(f&quot;Expected video tensor with 4 dims (T,C,H,W), got &#123;source.ndim&#125;&quot;)
        return source.float()

    if isinstance(source, list):
        frames = &#91;_pil_to_tensor(img) for img in source&#93;
        return torch.stack(frames)

    path = Path(source)
    if path.is_dir():
        return _load_frame_dir(path)
    return _load_video_file(str(path))</code></pre></details>
<h2 id="fastvideo.eval.io.video.extract_frames"><code>fastvideo.eval.io.video.extract_frames</code></h2>
<pre class="doc-signature"><code>extract_frames(video: torch.Tensor, n_frames: int | None = None) -&gt; torch.Tensor</code></pre>
<p>Uniformly sample <em>n_frames</em> from a <code>(T, C, H, W)</code> video tensor.</p>
<details><summary>Source</summary><pre><code>def extract_frames(video: torch.Tensor, n_frames: int | None = None) -&gt; torch.Tensor:
    &quot;&quot;&quot;Uniformly sample *n_frames* from a ``(T, C, H, W)`` video tensor.&quot;&quot;&quot;
    if n_frames is None or n_frames &gt;= video.shape&#91;0&#93;:
        return video
    indices = torch.linspace(0, video.shape&#91;0&#93; - 1, n_frames).long()
    return video&#91;indices&#93;</code></pre></details>
<h2 id="fastvideo.eval.io.video.probe_video_fps"><code>fastvideo.eval.io.video.probe_video_fps</code></h2>
<pre class="doc-signature"><code>probe_video_fps(source: str | Path) -&gt; float | None</code></pre>
<p>Read a path-backed video's native frame rate without decoding frames.</p>
<details><summary>Source</summary><pre><code>def probe_video_fps(source: str | Path) -&gt; float | None:
    &quot;&quot;&quot;Read a path-backed video&#x27;s native frame rate without decoding frames.&quot;&quot;&quot;
    try:
        import av

        with av.open(str(source)) as container:
            if not container.streams.video:
                return None
            stream = container.streams.video&#91;0&#93;
            rate = stream.average_rate or stream.guessed_rate
            if rate is not None and float(rate) &gt; 0:
                return float(rate)
    except (ImportError, OSError, ValueError):
        pass
    try:
        from decord import VideoReader, cpu

        rate = float(VideoReader(str(source), ctx=cpu(0)).get_avg_fps())
        return rate if rate &gt; 0 else None
    except (ImportError, OSError, RuntimeError, ValueError):
        return None</code></pre></details>
</div>
