{"record":{"id":"2fe6e313590aca6b","repo":"roboflow/supervision","slug":"videowriter-fourcc-requires-exactly-four-character","errorCode":null,"errorMessage":"VideoWriter_fourcc requires exactly four characters","messagePattern":"VideoWriter_fourcc requires exactly four characters","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/supervision/_cv2/_video.py","lineNumber":41,"sourceCode":"    _CAP_PROP_POS_FRAMES,\n)\n\nlogger = logging.getLogger(__name__)\n\n_CODECS = {\n    \"mp4v\": (\"mpeg4\", \"yuv420p\"),\n    \"xvid\": (\"mpeg4\", \"yuv420p\"),\n    \"avc1\": (\"libx264\", \"yuv420p\"),\n    \"h264\": (\"libx264\", \"yuv420p\"),\n    \"mjpg\": (\"mjpeg\", \"yuvj420p\"),\n    \"vp09\": (\"libvpx-vp9\", \"yuv420p\"),\n}\n\n\ndef _video_writer_fourcc(*chars: str) -> int:\n    \"\"\"Encode four single-character strings using OpenCV's integer layout.\"\"\"\n    if len(chars) != 4 or any(len(char) != 1 for char in chars):\n        raise TypeError(\"VideoWriter_fourcc requires exactly four characters\")\n    return sum(ord(char) << (8 * index) for index, char in enumerate(chars))\n\n\ndef _decode_fourcc(fourcc: int) -> str:\n    \"\"\"Decode a fourcc integer into its four-character representation.\"\"\"\n    return \"\".join(chr((fourcc >> (8 * index)) & 0xFF) for index in range(4))\n\n\ndef _codec_details(fourcc: int) -> tuple[str, str]:\n    \"\"\"Return the PyAV codec and pixel format for a supported fourcc.\"\"\"\n    code = _decode_fourcc(fourcc).lower()\n    try:\n        return _CODECS[code]\n    except KeyError as exc:\n        raise ValueError(f\"Unsupported video codec: {code!r}\") from exc\n\n\nclass _VideoCapture:","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/_cv2/_video.py#L23-L59","documentation":"cv2.VideoWriter_fourcc is called as four single-character arguments, e.g. VideoWriter_fourcc(*'mp4v'). The fallback encodes the fourcc integer by shifting each character's ordinal, so it raises TypeError when it receives anything other than exactly four one-character strings — passing the packed string 'mp4v' as one argument fails.","triggerScenarios":"Calling cv2.VideoWriter_fourcc('mp4v') (one 4-char string) instead of cv2.VideoWriter_fourcc(*'mp4v') or ('m','p','4','v'); also passing fewer/more than four arguments.","commonSituations":"The classic OpenCV idiom cv2.VideoWriter_fourcc(*'mp4v') works, but hand-written variations like VideoWriter_fourcc('mp4v') or unpacking a list of the wrong length are common copy-paste bugs.","solutions":["Spread the string: fourcc = cv2.VideoWriter_fourcc(*'mp4v').","Or pass four chars explicitly: cv2.VideoWriter_fourcc('m', 'p', '4', 'v').","If the codec comes as a variable, assert len(codec) == 4 before unpacking."],"exampleFix":"# before\nfourcc = cv2.VideoWriter_fourcc('mp4v')\n\n# after\nfourcc = cv2.VideoWriter_fourcc(*'mp4v')","handlingStrategy":"validation","validationCode":"codec = 'mp4v'\nassert len(codec) == 4 and codec.isascii()\nfourcc = cv2.VideoWriter_fourcc(*codec)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always spread: VideoWriter_fourcc(*codec)","Keep codec strings as exactly 4 ASCII chars","Validate codec length when it comes from user input"],"tags":["opencv-fallback","video-writer","fourcc","argument-unpacking"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}