roboflow/supervision · error · ValueError

Unsupported video codec: {code}

Error message

Unsupported video codec: {code}

What it means

The PyAV-based video writer fallback supports only a fixed codec table: mp4v, xvid, avc1, h264, mjpg, and vp09. _codec_details decodes the fourcc integer back to a string and looks it up; anything else raises ValueError instead of attempting an untested encoder mapping.

Source

Thrown at src/supervision/_cv2/_video.py:56

def _video_writer_fourcc(*chars: str) -> int:
    """Encode four single-character strings using OpenCV's integer layout."""
    if len(chars) != 4 or any(len(char) != 1 for char in chars):
        raise TypeError("VideoWriter_fourcc requires exactly four characters")
    return sum(ord(char) << (8 * index) for index, char in enumerate(chars))


def _decode_fourcc(fourcc: int) -> str:
    """Decode a fourcc integer into its four-character representation."""
    return "".join(chr((fourcc >> (8 * index)) & 0xFF) for index in range(4))


def _codec_details(fourcc: int) -> tuple[str, str]:
    """Return the PyAV codec and pixel format for a supported fourcc."""
    code = _decode_fourcc(fourcc).lower()
    try:
        return _CODECS[code]
    except KeyError as exc:
        raise ValueError(f"Unsupported video codec: {code!r}") from exc


class _VideoCapture:
    """Expose OpenCV-shaped file capture backed by PyAV decoding."""

    def __init__(self, source: str | os.PathLike[str] | int) -> None:
        """Open a file source and retain a lazy PyAV frame iterator."""
        self._container: Any = None
        self._stream: Any = None
        self._frames: Iterator[Any] | None = None
        self._source = source
        self._position = 0
        self._frame_count_cache: int | None = None
        self._opened = False
        self._error: Exception | None = None

        try:
            if isinstance(source, int):

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Use one of the supported fourccs: *'mp4v', *'xvid', *'avc1', *'h264', *'mjpg', or *'vp09'.
  2. Install opencv-python so VideoWriter uses real OpenCV backends with broader codec support.
  3. Match the container to the codec (.mp4 for mp4v/avc1/h264, .avi for xvid/mjpg, .webm for vp09).

Example fix

# before
fourcc = cv2.VideoWriter_fourcc(*'WMV1')
writer = cv2.VideoWriter('out.wmv', fourcc, 30, (w, h))

# after
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter('out.mp4', fourcc, 30, (w, h))
Defensive patterns

Strategy: fallback

Validate before calling

SUPPORTED_CODECS = {'mp4v', 'xvid', 'avc1', 'h264', 'mjpg', 'vp09'}
codec = codec if codec in SUPPORTED_CODECS else 'mp4v'
fourcc = cv2.VideoWriter_fourcc(*codec)

Try / catch

try:
    writer = cv2.VideoWriter(path, cv2.VideoWriter_fourcc(*codec), fps, size)
    if not writer.isOpened():
        writer = cv2.VideoWriter(path, cv2.VideoWriter_fourcc(*'mp4v'), fps, size)
except ValueError:
    writer = cv2.VideoWriter(path, cv2.VideoWriter_fourcc(*'mp4v'), fps, size)

Prevention

When it happens

Trigger: Creating a VideoWriter with a fourcc outside the table, e.g. 'WMV1', 'MJPG' variants that decode to unmapped codes, or a corrupted fourcc integer.

Common situations: Running in environments without opencv-python where Supervision writes video via PyAV; choosing a codec string from an OpenCV tutorial (e.g. 'DIVX', 'IYUV') that the fallback never mapped.

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/4072081bf2288a91. Report an issue: GitHub.