!7 import org.jcodec.api.awt.AWTSequenceEncoder8Bit; static int framesToEncode = 100000; p { inputFilePath("Video to modify", voidfunc(final File video) { thread { File outFile = prepareProgramFile(addSuffix("inverted-" + video.getName(), ".mp4")); int n = 0; for (BufferedImage img : framesFromVideo_reordering(video)) { print("Frames: " + n + "/" + framesToEncode); if (++n >= framesToEncode) break; } print("Wrote " + f2s(outFile) + " (" + n + " frames)"); } }); } // decoding part sclass LeftQueue { Iterator stream; RightQueue rightQueue; *(File video) { stream = framesFromVideo_reordering(video); } void step { if (stream != null && rightQueue.needImage()) if (stream.hasNext()) rightQueue.receive(stream.next()); else { stream = null; rightQueue.close(); } } } // encoding part sclass RightQueue { AWTSequenceEncoder8Bit enc; volatile BufferedImage img; int frames; *(File outMP4) { AWTSequenceEncoder8Bit enc = AWTSequenceEncoder8Bit.create25Fps(outMP4); enc.getEncoder().setKeyInterval(25); } void receive(BufferedImage img) { if (this.img != null) fail(); this.img = img; } bool needImage() { ret img == null; } void step { if (img != null) { img = invertedImage(img); enc.encodeImage(img); img = null; } } void close { enc.finish(); } }