sclass JFFMPEGVideoPlayer is Swingable { SurfaceShowingAutoZoomedImage surface; JPanel buttons = rightAlignedLine(); ImageStreamFromVideoFile stream; long playStartTime; { surface = swing(-> new SurfaceShowingAutoZoomedImage); buttons.add(jbutton("Open video...", rThread openDialog)); bindToComponent(surface, null, rThread closeStream); } visual centerAndSouthWithMargin( surface, buttons ); void openDialog swing { new JFileChooser fc; fc.setDialogTitle("Open video"); play(execFileChooser(fc)); } void play(File videoFile) { if (videoFile == null) ret; pcall-infobox { closeStream(); stream = new ImageStreamFromVideoFile; stream.open(videoFile); stream.onHaveImage((image, pos) -> { if (playStartTime == 0) playStartTime = sysNow()-pos.toMillis(); else sleepUntilSysTime(playStartTime+pos.toMillis()); surface.setImage(image); }); stream.startDecodeThread(); } } void closeStream { imageSurface.noImage(); dispose stream; playStartTime = 0; } }