What do open AI video tools (Wan2.2 save_video, diffusers export_to_video) actually write to the file: bit depth, encoder, colour tags, resolution?
Problem. A generated clip looks different after export (banding, size change, shifted levels) and nobody knows what the tool did. Conditions. Python tools that write MP4 through imageio/ffmpeg. Method (read from code). Wan2.2 wan/utils/utils.py save_video: tensor clamped to value_range (-1,1), made into a grid per frame, multiplied by 255 and cast with .type(torch.uint8), written with imageio.get_writer(codec='libx264', quality=8); fps default 30 in the signature. diffusers export_utils.export_to_video: float numpy frames become (frame*255).astype(np.uint8); imageio.get_writer with quality default 5 (variable bit rate; 10 highest), optional bitrate, and macro_block_size default 16, where imageio tells ffmpeg to scale the image up to the next size divisible by that number; set None or 1 to disable, with the warning that many players cannot decode odd sizes. Observations: (a) 8-bit output, so banding risk (C3-B586-01/02); (b) float to uint8 is a cast, not documented as rounded or dith...
Structured fields
{
"citations": [
{
"url": "https://raw.githubusercontent.com/Wan-Video/Wan2.2/main/wan/utils/utils.py",
"note": "save_video; save_video; export_to_video; export_to_video docstring; export_to_video docstring; export_to_video"
},
{
"url": "https://raw.githubusercontent.com/huggingface/diffusers/main/src/diffusers/utils/export_utils.py",
"note": "save_video; save_video; export_to_video; export_to_video docstring; export_to_video docstring; export_to_video"
}
]
}Evidence claims
- [sourced_fact] Problem. A generated clip looks different after export (banding, size change, shifted levels) and nobody knows what the tool did. Conditions. Python tools that write MP4 through imageio/ffmpeg. Method (read from code). Wan2.2 wan/utils/utils.py save_video: tensor clamped to value_range (-1,1), made into a grid per frame, multiplied by 255 and cast with .type(torch.uint8), written with imageio.get_writer(codec='libx264', quality=8); fps default 30 in the signature. diffusers export_utils.export_to_video: float numpy frames become (frame*255).astype(np.uint8); imageio.get_writer with quality default 5 (variable bit rate; 10 highest), optional bitrate, and macro_block_size default 16, where imageio tells ffmpeg to scale the image up to the next size divisible by that number; set None or 1 to disable, with the warning that many players cannot decode odd sizes. Observations: (a) 8-bit output, so banding risk (C3-B586-01/02); (b) float to uint8 is a cast, not documented as rounded or dithered [inference: numpy astype and torch .type(uint8) truncate toward zero, not tested here]; (c) the functions pass no colour primaries, transfer or range arguments, so any tag depends on imageio-ffmpeg defaults, which I did not read [absence in the code read is not proof of an untagged file; ffprobe the output]; (d) with macro_block_size 16 a 1080-line frame would be scaled to 1088 (1080/16 = 67.5) [inference from the doc sentence]. Action. ffprobe every file for resolution, pix_fmt and colour tags (see C3-B232-G71-05), tag explicitly if untagged (G71-02), and where the pipeline allows keep PIL or PNG frames instead of an MP4 as the hand-off. Failure modes. Silent rescale breaks pixel-exact compositing; low quality values add blocking on gradients. Limitations. Main-branch code on 2026-10-23; later commits may change defaults; other tools (ComfyUI video nodes etc.) not read. Version/date. diffusers and Wan2.2 main at fetch. · locator: save_video; save_video; export_to_video; export_to_video docstring; export_to_video docstring; export_to_video source
Rights
| component | license | hosting | redistribution | modification | training | Evidence and notes |
|---|---|---|---|---|---|---|
| documentation | unknown | permitted | permitted | unknown | unknown | Applies to this original summary only, not to the cited sources. |