#!/bin/sh /*/. 2>/dev/null; exec "$(dirname "$0")"/../../../bin/ImageJ.sh "$0" "$@" # exec with fiji */ import ij.IJ; import ij.gui.GenericDialog; import ij.io.SaveDialog; import fiji.User_Plugins; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.File; import java.io.PrintStream; import java.util.ArrayList; import java.util.regex.Pattern; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import org.scijava.util.LineOutputStream; import org.scijava.util.ReadInto; class IJLogOutputStream extends LineOutputStream { void println(String line) { IJ.log(line); } } class Options { boolean isWindows = System.getProperty("os.name").startsWith("Windows"); boolean isMac = System.getProperty("os.name").startsWith("Mac"); String vlc; File outputFile; double fps = 15; int outputWidth = 640; int top = -1, left = -1, width = -1, height = -1; boolean interactive = false; void error(message) { if (interactive) IJ.error(message); else print(message); } void showStatus(message) { if (interactive) IJ.showStatus(message); else print(message); } PrintStream getPrintStream() { if (interactive) return new PrintStream(new IJLogOutputStream()); return System.err; } } discoverVLC(options) { if (options.vlc != null) return; if (options.isWindows) { options.vlc = "C:\\Program Files\\VideoLAN\\VLC\\vlc.exe"; if (new File(options.vlc).exists()) return; options.vlc = "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe"; if (!new File(options.vlc).exists()) options.vlc = null; } else { for (String dir : System.getenv("PATH").split(":")) { file = new File(dir, "vlc"); if (file.exists()) options.vlc = file.getAbsolutePath(); } if (options.isMac) { file = new File("/Applications/VLC.app/Contents/MacOS/", "VLC"); if (file.exists()) { options.vlc = file.getAbsolutePath(); } } } } startScreencast(options) { outputPath = options.outputFile.getAbsolutePath(); options.showStatus("Screencasting to '" + options.outputFile + "'"); mux = "avi"; vcodec = "mp4v"; if (options.outputFile.getName().endsWith(".ogv")) { mux = "ogg"; vcodec = "theora"; } else if (options.outputFile.getName().endsWith(".mov")) { mux = "mov"; vcodec = "h264"; } commandLine = new ArrayList(); commandLine.add(options.vlc); commandLine.add("-I"); commandLine.add("dummy"); //commandLine.add("-vvv"); commandLine.add("screen://"); commandLine.add("--screen-fps=" + options.fps); if (options.left >= 0) { commandLine.add("--screen-left=" + options.left); commandLine.add("--screen-top=" + options.top); commandLine.add("--screen-width=" + options.width); commandLine.add("--screen-height=" + options.height); } if (options.isWindows) { commandLine.add("--dshow-fps=" + options.fps); } commandLine.add("--sout=#transcode{" + "vcodec=" + vcodec + "," + "vb=800," + "fps=" + options.fps + "," + "width=" + options.outputWidth + "," + "acodec=vorb," + "ab=128," + "channels=2," + "samplerate=22050" + "}:standard{" + "access=file," + "mux=" + mux + "," + "dst='" + outputPath + "'" + "}"); commandLine.add("vlc://quit"); commandLine = commandLine.toArray(new String[commandLine.size()]); if (!options.interactive) { print("Calling " + java.util.Arrays.toString(commandLine)); } Process process = Runtime.getRuntime().exec(commandLine, null, null); process.getOutputStream().close(); out = options.getPrintStream(); err = new ReadInto(process.getErrorStream(), out); out = new ReadInto(process.getInputStream(), out); ij = options.interactive ? IJ.getInstance() : null; if (ij != null) { item = fiji.FijiTools.getMenuItem("File>Make Screencast"); listeners = item.getActionListeners(); for (ActionListener listener : listeners) item.removeActionListener(listener); actionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { item.removeActionListener(this); IJ.showStatus("Stopping screencast"); process.destroy(); err.interrupt(); err.join(); out.interrupt(); out.join(); IJ.showStatus("Saved '" + options.outputFile + "'"); if (ij == null) System.exit(0); for (ActionListener listener : listeners) item.addActionListener(listener); item.setLabel("Make Screencast"); } }; item.setLabel("Stop Screencast"); item.addActionListener(actionListener); } } run(options) { discoverVLC(options); if (options.vlc == null) { options.error("Could not find VLC, please install"); if (options.interactive) { IJ.runPlugIn("ij.plugin.BrowserLauncher", "http://www.videolan.org/index.html"); } return; } startScreencast(options); } showUI() { options = new Options(); options.interactive = true; SaveDialog od = new SaveDialog("Save screencast as...", null, ".ogv"); directory = od.getDirectory(); fileName = od.getFileName(); if (directory == null || fileName == null) return null; options.outputFile = new File(directory, fileName); if (options.outputFile == null) return null; // canceled if (options.outputFile.exists() && options.outputFile.length() != 0 && !IJ.showMessageWithCancel("Overwrite?", "The file '" + options.outputFile + "' appears to exist already. Overwrite?")) { return null; } options.outputWidth = (int)IJ.getNumber("Width", Toolkit.getDefaultToolkit().getScreenSize().width); if (options.outputWidth < 0) return null; return options; } usage() { System.err.println("Usage: " + this.interpreter.getSourceFileInfo() + " [--force] [--width ] [--fps ] [--geometry ] "); System.exit(1); } parseCommandLine() { options = new Options(); force = false; for (i = 0; i < bsh.args.length && bsh.args[i].startsWith("-"); i++) { if (bsh.args[i].equals("--force")) { force = true; } else if (bsh.args[i].equals("--width")) { options.outputWidth = Integer.parseInt(bsh.args[++i]); } else if (bsh.args[i].equals("--fps")) { options.fps = Double.parseDouble(bsh.args[++i]); } else if (bsh.args[i].equals("--geometry")) { pattern = Pattern.compile("(\\d+)x(\\d+)\\+(\\d+)\\+(\\d+)"); matcher = pattern.matcher(bsh.args[++i]); if (!matcher.matches()) { print("Invalid geometry: " + bsh.args[i]); usage(); } options.width = Integer.parseInt(matcher.group(1)); options.height = Integer.parseInt(matcher.group(2)); options.left = Integer.parseInt(matcher.group(3)); options.top = Integer.parseInt(matcher.group(4)); } else { print("Unknown option: " + bsh.args[i]); usage(); } } if (i + 1 != bsh.args.length) { print("The last argument must be the output file!"); usage(); } options.outputFile = new File(bsh.args[i]); if (!force && options.outputFile.exists()) { print("File '" + options.outputFile + "' exists already."); System.exit(1); } return options; } if (IJ.getInstance() == null) options = parseCommandLine(); else options = showUI(); if (options != null) { run(options); }