def compress_video(x: np.ndarray, video_format: str, constant_rate_factor: int, dir_: str = ""):
            """
            Apply video compression to video input of shape (frames, height, width, channel).
            """
            import ffmpeg

            video_path = os.path.join(dir_, f"tmp_video.{video_format}")
            _, height, width, _ = x.shape

            if (height % 2) != 0 or (width % 2) != 0:
                warnings.warn("Codec might require even number of pixels in height and width.")

            # numpy to local video file
            process = (
                ffmpeg.input("pipe:", format="rawvideo", pix_fmt="rgb24", s=f"{width}x{height}")
                .output(video_path, pix_fmt="yuv420p", vcodec="libx264", crf=constant_rate_factor)
                .overwrite_output()
                .run_async(pipe_stdin=True, quiet=True)
            )
            process.stdin.write(x.flatten().astype(np.uint8).tobytes())
            process.stdin.close()
            process.wait()

            # local video file to numpy
            stdout, _ = (
                ffmpeg.input(video_path)
                .output("pipe:", format="rawvideo", pix_fmt="rgb24")
                .run(capture_stdout=True, quiet=True)
            )
            return np.frombuffer(stdout, np.uint8).reshape(x.shape)

            Apply video compression to video input of shape (frames, height, width, channel).
            
art/defences/preprocessor/video_compression.py