def test_write_gif(util, clip_class, opt, loop, with_mask, pixel_format): filename = os.path.join(util.TMP_DIR, "moviepy_write_gif.gif") if os.path.isfile(filename): os.remove(filename) fps = 10 if clip_class == "BitmapClip": original_clip = BitmapClip([["R"], ["G"], ["B"]], fps=fps).with_duration(0.3) else: original_clip = concatenate_videoclips([ ColorClip( (1, 1), color=color, ).with_duration(0.1).with_fps(fps) for color in [(255, 0, 0), (0, 255, 0), (0, 0, 255)] ]) if with_mask: original_clip = original_clip.with_mask( ColorClip((1, 1), color=1, is_mask=True).with_fps(fps).with_duration(0.3)) kwargs = {} if pixel_format is not None: kwargs["pixel_format"] = pixel_format write_gif( original_clip, filename, fps=fps, with_mask=with_mask, program="ffmpeg", logger=None, opt=opt, loop=loop, **kwargs, ) if pixel_format != "invalid": final_clip = VideoFileClip(filename) r, g, b = final_clip.get_frame(0)[0][0] assert r == 252 assert g == 0 assert b == 0 r, g, b = final_clip.get_frame(0.1)[0][0] assert r == 0 assert g == 252 assert b == 0 r, g, b = final_clip.get_frame(0.2)[0][0] assert r == 0 assert g == 0 assert b == 255 assert final_clip.duration == (loop or 1) * round( original_clip.duration, 6)
def test_save_frame(util, with_mask, t, mask_color, frames): filename = os.path.join(util.TMP_DIR, "moviepy_VideoClip_save_frame.png") if os.path.isfile(filename): try: os.remove(filename) except PermissionError: pass width, height = (len(frames[0][0]), len(frames[0])) clip = BitmapClip(frames, fps=1) if with_mask: mask = ColorClip(color=mask_color, is_mask=True, size=(width, height)) clip = clip.with_mask(mask) clip.save_frame(filename, t) t = int(convert_to_seconds(t)) # expected RGB e_r, e_g, e_b = BitmapClip.DEFAULT_COLOR_DICT[frames[t][0][0]] im = Image.open(filename, mode="r") assert im.width == width assert im.height == height for i in range(im.width): for j in range(im.height): rgba = im.getpixel((i, j)) if len(rgba) == 4: r, g, b, a = rgba else: r, g, b = rgba assert r == e_r assert g == e_g assert b == e_b if with_mask: assert round(a / 254, 2) == mask_color
def test_ffmpeg_write_video( util, codec, is_valid_codec, ext, write_logfile, with_mask, bitrate, threads, ): filename = os.path.join(util.TMP_DIR, f"moviepy_ffmpeg_write_video{ext}") if os.path.isfile(filename): try: os.remove(filename) except PermissionError: pass logfile_name = filename + ".log" if os.path.isfile(logfile_name): os.remove(logfile_name) clip = BitmapClip([["R"], ["G"], ["B"]], fps=10).with_duration(0.3) if with_mask: clip = clip.with_mask( BitmapClip([["W"], ["O"], ["O"]], fps=10, is_mask=True).with_duration(0.3)) kwargs = dict( logger=None, write_logfile=write_logfile, with_mask=with_mask, ) if codec is not None: kwargs["codec"] = codec if bitrate is not None: kwargs["bitrate"] = bitrate if threads is not None: kwargs["threads"] = threads ffmpeg_write_video(clip, filename, 10, **kwargs) if is_valid_codec: assert os.path.isfile(filename) final_clip = VideoFileClip(filename) r, g, b = final_clip.get_frame(0)[0][0] assert r == 254 assert g == 0 assert b == 0 r, g, b = final_clip.get_frame(0.1)[0][0] assert r == (0 if not with_mask else 1) assert g == (255 if not with_mask else 1) assert b == 1 r, g, b = final_clip.get_frame(0.2)[0][0] assert r == 0 assert g == 0 assert b == (255 if not with_mask else 0) if write_logfile: assert os.path.isfile(logfile_name)