import av | |
from pathlib import Path | |
import os | |
def save_videos_from_pil(pil_images, path, fps=8, bitrate=None): | |
save_fmt = Path(path).suffix | |
os.makedirs(os.path.dirname(path), exist_ok=True) | |
width, height = pil_images[0].size | |
if save_fmt == ".mp4": | |
codec = "libx264" | |
container = av.open(path, "w") | |
stream = container.add_stream(codec, rate=fps, ) | |
stream.width = width | |
stream.height = height | |
if bitrate is not None: | |
stream.bit_rate = bitrate | |
for pil_image in pil_images: | |
av_frame = av.VideoFrame.from_image(pil_image) | |
container.mux(stream.encode(av_frame)) | |
container.mux(stream.encode()) | |
container.close() | |
elif save_fmt == ".gif": | |
pil_images[0].save( | |
fp=path, | |
format="GIF", | |
append_images=pil_images[1:], | |
save_all=True, | |
duration=(1 / fps * 1000), | |
loop=0, | |
) | |
else: | |
raise ValueError("Unsupported file type. Use .mp4 or .gif.") |