NDR: add sample and virtualdub plug-in
authorgreenmarine <greenmarine@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Thu, 11 Feb 2010 16:02:26 +0000 (16:02 +0000)
committergreenmarine <greenmarine@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Thu, 11 Feb 2010 16:02:26 +0000 (16:02 +0000)
git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8637 f962a42d-fe04-0410-a3ab-8c8b0445ebaa

misc/tools/NexuizDemoRecorder/main/pom.xml [moved from misc/tools/NexuizDemoRecorder/pom.xml with 100% similarity]
misc/tools/NexuizDemoRecorder/plugins/sample/pom.xml [new file with mode: 0644]
misc/tools/NexuizDemoRecorder/plugins/sample/src/main/java/com/nexuiz/demorecorder/application/plugins/impl/sample/SamplePlugin.java [new file with mode: 0644]
misc/tools/NexuizDemoRecorder/plugins/sample/src/main/resources/META-INF/services/com.nexuiz.demorecorder.application.plugins.EncoderPlugin [new file with mode: 0644]
misc/tools/NexuizDemoRecorder/plugins/virtualdub/pom.xml [new file with mode: 0644]
misc/tools/NexuizDemoRecorder/plugins/virtualdub/src/main/java/com/nexuiz/demorecorder/application/plugins/impl/virtualdub/VirtualDubPlugin.java [new file with mode: 0644]
misc/tools/NexuizDemoRecorder/plugins/virtualdub/src/main/resources/META-INF/services/com.nexuiz.demorecorder.application.plugins.EncoderPlugin [new file with mode: 0644]

diff --git a/misc/tools/NexuizDemoRecorder/plugins/sample/pom.xml b/misc/tools/NexuizDemoRecorder/plugins/sample/pom.xml
new file mode 100644 (file)
index 0000000..b240c0e
--- /dev/null
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">\r
+       <modelVersion>4.0.0</modelVersion>\r
+       <groupId>NexuizDemoRecorder</groupId>\r
+       <artifactId>SamplePlugin</artifactId>\r
+       <version>0.0.1-SNAPSHOT</version>\r
+       <dependencies>\r
+               <dependency>\r
+                       <groupId>NexuizDemoRecorder</groupId>\r
+                       <artifactId>NexuizDemoRecorder</artifactId>\r
+                       <version>0.2</version>\r
+                       <scope>provided</scope>\r
+               </dependency>\r
+       </dependencies>\r
+       <build>\r
+               <resources>\r
+                       <resource>\r
+                               <directory>src/main/resources</directory>\r
+                       </resource>\r
+               </resources>\r
+               <plugins>\r
+                       <plugin>\r
+                               <groupId>org.apache.maven.plugins</groupId>\r
+                               <artifactId>maven-compiler-plugin</artifactId>\r
+                               <version>2.0.2</version>\r
+                               <configuration>\r
+                                       <source>1.6</source>\r
+                                       <target>1.6</target>\r
+                               </configuration>\r
+                       </plugin>\r
+\r
+\r
+               </plugins>\r
+       </build>\r
+</project>
\ No newline at end of file
diff --git a/misc/tools/NexuizDemoRecorder/plugins/sample/src/main/java/com/nexuiz/demorecorder/application/plugins/impl/sample/SamplePlugin.java b/misc/tools/NexuizDemoRecorder/plugins/sample/src/main/java/com/nexuiz/demorecorder/application/plugins/impl/sample/SamplePlugin.java
new file mode 100644 (file)
index 0000000..72b0f73
--- /dev/null
@@ -0,0 +1,202 @@
+package com.nexuiz.demorecorder.application.plugins.impl.sample;\r
+\r
+import java.util.Properties;\r
+\r
+import com.nexuiz.demorecorder.application.DemoRecorderApplication;\r
+import com.nexuiz.demorecorder.application.jobs.RecordJob;\r
+import com.nexuiz.demorecorder.application.plugins.EncoderPlugin;\r
+import com.nexuiz.demorecorder.application.plugins.EncoderPluginException;\r
+\r
+/**\r
+ * This is a sample plug-in implementation. It does not really do anything, but it\r
+ * is supposed to show you how to implement a plug-in and where to do what.\r
+ * \r
+ * First of all, it is important that your final jar file (you can have Maven create\r
+ * it for you) contains the META-INF folder (it will have that one anyway), and within\r
+ * that folder you must have the folder "services", in which you must have a file called\r
+ * com.nexuiz.demorecorder.application.plugins.EncoderPlugin (this is the fully\r
+ * qualified name of the interface you need to implement, EncoderPlugin).\r
+ * This file needs to contain just one line: the fully qualified name to your\r
+ * implementation class!\r
+ * \r
+ * Okay. The Nexuiz Demo Recorder (NDR) gives your plug-in 2 kinds of possibilities to\r
+ * configure it ("set it up") from within the NDR. Configuring the plug-in is also \r
+ * referred to as "setting preferences". There are \r
+ * - Global preferences: these will be shown in the "Preferences" dialog of the NDR\r
+ * - Job-specific preferences: these will be shown in the dialog you get when creating\r
+ *   new jobs or templates, or when editing them\r
+ * \r
+ * Once the NDR loaded your plug-in, the first thing it will do is to call \r
+ * setApplicationLayer(), handing your plug-in the reference to the app-layer. Make sure that\r
+ * you save it in a private member variable!\r
+ * \r
+ * NDR will ask your plug-in to tell it about its global and job-specific preferences that exist.\r
+ * For each of these 2 kinds of preferences it will also ask you for the order in which you want\r
+ * these settings to appear in dialogs.\r
+ * \r
+ * The methods that ask you to return a Properties object: create a new Properties object and fill\r
+ * it with KEYS (that identify the setting), and VALUES (reasonable default values). The app-layer\r
+ * will save these "new" settings in the app_preferences.xml in the "settings" folder once NDR\r
+ * is closed (this applies only to the global settings!). That just means that, later on, to figure\r
+ * out whether the user changed settings from their default value, you need to ask the app-layer\r
+ * for its preferences object (that might have been manipulated by the user using the GUI) and look\r
+ * for "your" settings in that Properties object. A good example is the isEnabled() method.\r
+ */\r
+public class SamplePlugin implements EncoderPlugin {\r
+       \r
+       /**\r
+        *  Do not put the word "plug-in" in here, that would be redundant.\r
+        */\r
+       private static final String PLUGIN_NAME = "Sample";\r
+       \r
+       /**\r
+        * Here we store our preferences. It is not necessary that these are in a inner-class, do it in\r
+        * your way if you want.\r
+        */\r
+       private static class Preferences {\r
+               /*\r
+                * Lets start with GLOBAL settings which will be seen in the Preferences dialog of the NDR\r
+                */\r
+               public static final String ENABLED = "Enabled"; //we will need this! "Enabled" means that\r
+                                                                       //that the preferences dialog will show the exact word "Enabled"\r
+               \r
+               public static final String SAMPLE_SETTING = "Some sample setting";\r
+               \r
+               /*\r
+                * Now we define the order in which we want these to be shown.\r
+                */\r
+               public static final String[] GLOBAL_PREFERENCES_ORDER = {\r
+                       ENABLED,\r
+                       SAMPLE_SETTING\r
+               };\r
+               \r
+               //job-specific preferences\r
+               public static final String IN_USE_FOR_THIS_JOB = "Do something for this job";\r
+               \r
+               /*\r
+                * OK, so far we have actually only created labels. But we also need default values\r
+                * So let's have a function that sets the default values up.\r
+                */\r
+               public static Properties globalDefaultPreferences = new Properties();\r
+               public static void createPreferenceDefaultValues() {\r
+                       globalDefaultPreferences.setProperty(ENABLED, "false");\r
+                       globalDefaultPreferences.setProperty(SAMPLE_SETTING, "filechooser");\r
+                       /*\r
+                        * Note that the values for the defaults can be:\r
+                        * - "true" or "false", in this case the GUI will show a check-box\r
+                        * - "filechooser", in this case the GUI will show a button that allows the user to select\r
+                        *    a file\r
+                        * - anything else (also empty string if you like): will show a text field in the GUI\r
+                        *   (you are in charge of parsing it)\r
+                        */\r
+               }\r
+               \r
+       }\r
+       \r
+       private DemoRecorderApplication appLayer;\r
+       \r
+       /**\r
+        * You must only have a default constructor without parameters!\r
+        */\r
+       public SamplePlugin() {\r
+               Preferences.createPreferenceDefaultValues();\r
+       }\r
+\r
+       \r
+\r
+       @Override\r
+       public Properties getGlobalPreferences() {\r
+               return Preferences.globalDefaultPreferences;\r
+       }\r
+\r
+       @Override\r
+       public String[] getGlobalPreferencesOrder() {\r
+               return Preferences.GLOBAL_PREFERENCES_ORDER;\r
+       }\r
+\r
+       @Override\r
+       public Properties getJobSpecificPreferences() {\r
+               /*\r
+                * This method is called whenever the dialog to create new jobs/templates (or edit them)\r
+                * is opened. This means that you can dynamically create the returned Properties object\r
+                * if you like, or you could of course also return something static.\r
+                */\r
+               Properties preferences = new Properties();\r
+               preferences.setProperty(Preferences.IN_USE_FOR_THIS_JOB, "true");\r
+               return preferences;\r
+       }\r
+\r
+       @Override\r
+       public String[] getJobSpecificPreferencesOrder() {\r
+               String[] order = {Preferences.IN_USE_FOR_THIS_JOB};\r
+               return order;\r
+       }\r
+\r
+       @Override\r
+       public String getName() {\r
+               return PLUGIN_NAME;\r
+       }\r
+       \r
+       @Override\r
+       public void setApplicationLayer(DemoRecorderApplication appLayer) {\r
+               this.appLayer = appLayer;\r
+       }\r
+\r
+       @Override\r
+       public boolean isEnabled() {\r
+               /*\r
+                * Here we get the Properties object of the app-layer. Notice that this is actually a\r
+                * NDRPreferences object. It has a new method getProperty(String category, String key).\r
+                * The category is the name of our plug-in. The key is obviously our own ENABLED key.\r
+                */\r
+               String enabledString = this.appLayer.getPreferences().getProperty(PLUGIN_NAME, Preferences.ENABLED);\r
+               return Boolean.valueOf(enabledString);\r
+       }\r
+       \r
+       @Override\r
+       public void executeEncoder(RecordJob job) throws EncoderPluginException {\r
+               /*\r
+                * This is where the party gets started.\r
+                * Of course you need to check whether your plug-in is enabled by the user, and whether the\r
+                * job-specific settings are set correctly. So let's do this now:\r
+                */\r
+               if (!this.isEnabled()) {\r
+                       return;\r
+               }\r
+               \r
+               if (job.getActualVideoDestination() == null) {\r
+                       //should never happen... but just to make sure!\r
+                       throw new EncoderPluginException("Actual video destination is not set (should have been set when processing the job)");\r
+               }\r
+               \r
+               if (!job.getActualVideoDestination().exists()) {\r
+                       throw new EncoderPluginException("Could not locate recorded video file (source) at location "\r
+                                       + job.getActualVideoDestination().getAbsolutePath());\r
+               }\r
+               \r
+               //check for a job-specific setting ... this time we need it from the job:\r
+               Properties jobSpecificSettings = job.getEncoderPluginSettings(this);\r
+               String isEnabled = jobSpecificSettings.getProperty(Preferences.IN_USE_FOR_THIS_JOB);\r
+               if (!Boolean.valueOf(isEnabled)) {\r
+                       //the job does not want our plug-in to be executed, d'oh\r
+                       throw new EncoderPluginException("We are not enabled to do anything for this job :-(");\r
+                       //of course in a real implementation, instead of throwing an exception we'd just "return;"\r
+               }\r
+               \r
+               /*\r
+                * Now we can start doing the work. What you'll normally do is to construct a big string that you then have executed\r
+                * Have a look at the VirtualDub plug-in implementation to see how I did it.\r
+                * \r
+                * IMPORTANT: unless you parse the output of the console when executing a shell command (to check whether\r
+                * the encoder threw error messages at you), it is recommended that you create a log file of each job.\r
+                * The VirtualDub plug-in also provides an example of how to do that.\r
+                * \r
+                * Also notice the use of the EncoderPluginException. Whenever something goes wrong, throw this exception.\r
+                * Note that there is also another constructor EncoderPluginException(String message, Throwable t) where you\r
+                * can attach the original exception.\r
+                */\r
+       }\r
+\r
+       \r
+\r
+}\r
diff --git a/misc/tools/NexuizDemoRecorder/plugins/sample/src/main/resources/META-INF/services/com.nexuiz.demorecorder.application.plugins.EncoderPlugin b/misc/tools/NexuizDemoRecorder/plugins/sample/src/main/resources/META-INF/services/com.nexuiz.demorecorder.application.plugins.EncoderPlugin
new file mode 100644 (file)
index 0000000..b90fe46
--- /dev/null
@@ -0,0 +1 @@
+com.nexuiz.demorecorder.application.plugins.impl.sample.SamplePlugin\r
diff --git a/misc/tools/NexuizDemoRecorder/plugins/virtualdub/pom.xml b/misc/tools/NexuizDemoRecorder/plugins/virtualdub/pom.xml
new file mode 100644 (file)
index 0000000..5da6d88
--- /dev/null
@@ -0,0 +1,38 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>NexuizDemoRecorder</groupId>
+       <artifactId>VirtualDubPlugin</artifactId>
+       <packaging>jar</packaging>
+       <version>1.0</version>
+       <name>VirtualDubPlugin</name>
+       <url>http://maven.apache.org</url>
+       <dependencies>
+               <dependency>
+                       <groupId>NexuizDemoRecorder</groupId>
+                       <artifactId>NexuizDemoRecorder</artifactId>
+                       <version>0.2</version>
+                       <scope>provided</scope>
+               </dependency>
+       </dependencies>
+       <build>
+               <resources>
+                       <resource>
+                               <directory>src/main/resources</directory>
+                       </resource>
+               </resources>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <version>2.0.2</version>
+                               <configuration>
+                                       <source>1.6</source>
+                                       <target>1.6</target>
+                               </configuration>
+                       </plugin>
+
+
+               </plugins>
+       </build>
+</project>
diff --git a/misc/tools/NexuizDemoRecorder/plugins/virtualdub/src/main/java/com/nexuiz/demorecorder/application/plugins/impl/virtualdub/VirtualDubPlugin.java b/misc/tools/NexuizDemoRecorder/plugins/virtualdub/src/main/java/com/nexuiz/demorecorder/application/plugins/impl/virtualdub/VirtualDubPlugin.java
new file mode 100644 (file)
index 0000000..6f95540
--- /dev/null
@@ -0,0 +1,355 @@
+package com.nexuiz.demorecorder.application.plugins.impl.virtualdub;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.BufferedWriter;\r
+import java.io.File;\r
+import java.io.FileWriter;\r
+import java.io.IOException;\r
+import java.io.InputStreamReader;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Properties;\r
+\r
+import com.nexuiz.demorecorder.application.DemoRecorderApplication;\r
+import com.nexuiz.demorecorder.application.DemoRecorderException;\r
+import com.nexuiz.demorecorder.application.DemoRecorderUtils;\r
+import com.nexuiz.demorecorder.application.jobs.RecordJob;\r
+import com.nexuiz.demorecorder.application.plugins.EncoderPlugin;\r
+import com.nexuiz.demorecorder.application.plugins.EncoderPluginException;\r
+\r
+public class VirtualDubPlugin implements EncoderPlugin {\r
+       \r
+       private static final String PLUGIN_NAME = "Virtual Dub";\r
+       \r
+       private static class Preferences {\r
+               public static final String ENABLED = "Enabled";\r
+               public static final String VIRTUAL_DUB_BINARY_PATH = "Path to vdub.exe";\r
+               public static final String VCF_PER_JOB_LIMIT = "Max. number of VCFs per job";\r
+               public static final String OUTPUT_FILE_MODE = "Output as suffix (0) or file (1)";\r
+               public static final String EXTRA_OPTIONS = "Show extra options";\r
+               \r
+               public static final String[] GLOBAL_PREFERENCES_ORDER = {\r
+                       ENABLED,\r
+                       VIRTUAL_DUB_BINARY_PATH,\r
+                       VCF_PER_JOB_LIMIT,\r
+                       OUTPUT_FILE_MODE,\r
+                       EXTRA_OPTIONS\r
+               };\r
+               \r
+               //job-specific preferences\r
+               public static final String CLEAR_JOBCONTROL = "Clear VDub job control on first VCF";\r
+               public static final String RENDER_OUTPUT = "VDub renders queued jobs";\r
+               public static final String VCF_PATH = "Path to VCF file "; //x will be attached, e.g. "Path to VCF file 1"\r
+               public static final String OUTPUT_SUFFIX = "Suffix for output file "; //x will be attached, e.g. "Suffix for output file 1"\r
+               public static final String OUTPUT_FILE = "Output file "; //x will be attached\r
+               public static final String USE_ENCODED_VIDEO = "<HTML><BODY>Use encoded video from VCF "; //x will be attached\r
+               public static final String USE_ENCODED_VIDEO_2 = "<BR>for consecutive VCFs</BODY></HTML>";\r
+               public static final String DELETE_ORIG_FILE = "Delete orig. file after processing VCF "; //x will be attached\r
+       }\r
+       \r
+       private DemoRecorderApplication appLayer = null;\r
+       private Properties globalDefaultPreferences = new Properties();\r
+       \r
+       public VirtualDubPlugin() {\r
+               this.createPreferenceDefaultValues();\r
+       }\r
+\r
+       @Override\r
+       public void executeEncoder(RecordJob job) throws EncoderPluginException {\r
+               this.checkAppLayer();\r
+               if (!this.isEnabled()) {\r
+                       return;\r
+               }\r
+               \r
+               if (job.getActualVideoDestination() == null) {\r
+                       //should never happen... but just to make sure!\r
+                       throw new EncoderPluginException("Actual video destination is not set (should have been set when processing the job)");\r
+               }\r
+               \r
+               if (!job.getActualVideoDestination().exists()) {\r
+                       throw new EncoderPluginException("Could not locate video file (source) at location "\r
+                                       + job.getActualVideoDestination().getAbsolutePath());\r
+               }\r
+               \r
+               String limitStr = this.appLayer.getPreferences().getProperty(this.getName(), Preferences.VCF_PER_JOB_LIMIT);\r
+               int vcfCounter;\r
+               try {\r
+                       vcfCounter = Integer.valueOf(limitStr);\r
+               } catch (NumberFormatException e) {\r
+                       throw new EncoderPluginException("Invalid value \"" + limitStr + "\" for setting " + Preferences.VCF_PER_JOB_LIMIT);\r
+               }\r
+               \r
+               //check vdub.exe\r
+               String vDubBinary = this.appLayer.getPreferences().getProperty(this.getName(), Preferences.VIRTUAL_DUB_BINARY_PATH);\r
+               File vDubBinaryFile = new File(vDubBinary);\r
+               if (!vDubBinaryFile.exists() || !vDubBinaryFile.canExecute()) {\r
+                       throw new EncoderPluginException("Invalid location for the vdub.exe: " + vDubBinary);\r
+               }\r
+               \r
+               this.doEncoding(job, vcfCounter);\r
+       }\r
+\r
+       @Override\r
+       public Properties getGlobalPreferences() {\r
+               return this.globalDefaultPreferences;\r
+       }\r
+\r
+       @Override\r
+       public String[] getGlobalPreferencesOrder() {\r
+               return Preferences.GLOBAL_PREFERENCES_ORDER;\r
+       }\r
+\r
+       @Override\r
+       public Properties getJobSpecificPreferences() {\r
+               this.checkAppLayer();\r
+               Properties jobSpecificPreferences = new Properties();\r
+               \r
+               //static properties\r
+               jobSpecificPreferences.setProperty(Preferences.CLEAR_JOBCONTROL, "true");\r
+               jobSpecificPreferences.setProperty(Preferences.RENDER_OUTPUT, "true");\r
+               \r
+               //dynamic properties\r
+               String limitStr = this.appLayer.getPreferences().getProperty(this.getName(), Preferences.VCF_PER_JOB_LIMIT);\r
+               try {\r
+                       int limit = Integer.valueOf(limitStr);\r
+                       if (limit > 0) {\r
+                               for (int i = 1; i <= limit; i++) {\r
+                                       jobSpecificPreferences.setProperty(Preferences.VCF_PATH + i, "filechooser");\r
+                                       if (Boolean.valueOf(this.appLayer.getPreferences().getProperty(this.getName(), Preferences.OUTPUT_FILE_MODE))) {\r
+                                               //filechooser\r
+                                               jobSpecificPreferences.setProperty(Preferences.OUTPUT_FILE + i, "filechooser");\r
+                                       } else {\r
+                                               //suffix\r
+                                               jobSpecificPreferences.setProperty(Preferences.OUTPUT_SUFFIX + i, "_vdub" + i);\r
+                                       }\r
+                                       \r
+                                       if (Boolean.valueOf(this.appLayer.getPreferences().getProperty(this.getName(), Preferences.EXTRA_OPTIONS))) {\r
+                                               String useEncStringKey = Preferences.USE_ENCODED_VIDEO + i + Preferences.USE_ENCODED_VIDEO_2;\r
+                                               jobSpecificPreferences.setProperty(useEncStringKey, "false");\r
+                                               jobSpecificPreferences.setProperty(Preferences.DELETE_ORIG_FILE + i, "false");\r
+                                       }\r
+                               }\r
+                       }\r
+               } catch (NumberFormatException e) {\r
+                       throw new DemoRecorderException("Invalid value \"" + limitStr + "\" for setting " + Preferences.VCF_PER_JOB_LIMIT);\r
+               }\r
+               \r
+               return jobSpecificPreferences;\r
+       }\r
+       \r
+       @Override\r
+       public String[] getJobSpecificPreferencesOrder() {\r
+               this.checkAppLayer();\r
+               List<String> preferencesOrderList = new ArrayList<String>();\r
+               \r
+               //static properties\r
+               preferencesOrderList.add(Preferences.CLEAR_JOBCONTROL);\r
+               preferencesOrderList.add(Preferences.RENDER_OUTPUT);\r
+               \r
+               //dynamic properties\r
+               String limitStr = this.appLayer.getPreferences().getProperty(this.getName(), Preferences.VCF_PER_JOB_LIMIT);\r
+               try {\r
+                       int limit = Integer.valueOf(limitStr);\r
+                       if (limit > 0) {\r
+                               for (int i = 1; i <= limit; i++) {\r
+                                       preferencesOrderList.add(Preferences.VCF_PATH + i);\r
+                                       if (Boolean.valueOf(this.appLayer.getPreferences().getProperty(this.getName(), Preferences.OUTPUT_FILE_MODE))) {\r
+                                               //filechooser\r
+                                               preferencesOrderList.add(Preferences.OUTPUT_FILE + i);\r
+                                       } else {\r
+                                               //suffix\r
+                                               preferencesOrderList.add(Preferences.OUTPUT_SUFFIX + i);\r
+                                       }\r
+                                       \r
+                                       if (Boolean.valueOf(this.appLayer.getPreferences().getProperty(this.getName(), Preferences.EXTRA_OPTIONS))) {\r
+                                               String useEncStringKey = Preferences.USE_ENCODED_VIDEO + i + Preferences.USE_ENCODED_VIDEO_2;\r
+                                               preferencesOrderList.add(useEncStringKey);\r
+                                               preferencesOrderList.add(Preferences.DELETE_ORIG_FILE + i);\r
+                                       }\r
+                               }\r
+                       }\r
+               } catch (NumberFormatException e) {\r
+                       throw new DemoRecorderException("Invalid value \"" + limitStr + "\" for setting " + Preferences.VCF_PER_JOB_LIMIT);\r
+               }\r
+               \r
+               Object[] arr = preferencesOrderList.toArray();\r
+               String[] stringArr = new String[arr.length];\r
+               for (int i = 0; i < arr.length; i++) {\r
+                       stringArr[i] = (String) arr[i];\r
+               }\r
+               \r
+               return stringArr;\r
+       }\r
+\r
+       @Override\r
+       public String getName() {\r
+               return PLUGIN_NAME;\r
+       }\r
+\r
+       @Override\r
+       public boolean isEnabled() {\r
+               this.checkAppLayer();\r
+               String enabledString = this.appLayer.getPreferences().getProperty(this.getName(), Preferences.ENABLED);\r
+               return Boolean.valueOf(enabledString);\r
+       }\r
+\r
+       @Override\r
+       public void setApplicationLayer(DemoRecorderApplication appLayer) {\r
+               this.appLayer = appLayer;\r
+       }\r
+       \r
+       private void checkAppLayer() {\r
+               if (this.appLayer == null) {\r
+                       throw new DemoRecorderException("Error in plugin " + PLUGIN_NAME + "! Application layer not set!");\r
+               }\r
+       }\r
+       \r
+       private void createPreferenceDefaultValues() {\r
+               this.globalDefaultPreferences.setProperty(Preferences.ENABLED, "false");\r
+               this.globalDefaultPreferences.setProperty(Preferences.VIRTUAL_DUB_BINARY_PATH, "filechooser");\r
+               this.globalDefaultPreferences.setProperty(Preferences.VCF_PER_JOB_LIMIT, "1");\r
+               this.globalDefaultPreferences.setProperty(Preferences.OUTPUT_FILE_MODE, "false");\r
+               this.globalDefaultPreferences.setProperty(Preferences.EXTRA_OPTIONS, "false");\r
+       }\r
+       \r
+       private void doEncoding(RecordJob job, int vcfCounter) throws EncoderPluginException {\r
+               boolean firstValidVCF = true;\r
+               for (int i = 1; i <= vcfCounter; i++) {\r
+                       Properties jobSpecificSettings = job.getEncoderPluginSettings(this);\r
+                       String path = jobSpecificSettings.getProperty(Preferences.VCF_PATH + i);\r
+                       if (path != null) {\r
+                               File vcfFile = new File(path);\r
+                               if (vcfFile.exists()) {\r
+                                       if (Boolean.valueOf(this.appLayer.getPreferences().getProperty(this.getName(), Preferences.OUTPUT_FILE_MODE))) {\r
+                                               //filechooser\r
+                                               String outputPath = jobSpecificSettings.getProperty(Preferences.OUTPUT_FILE + i, "filechooser");\r
+                                               if (outputPath == null || outputPath.equals("") || outputPath.equals("filechoose")) {\r
+                                                       //user has not yet selected a file\r
+                                                       continue;\r
+                                               }\r
+                                       } else {\r
+                                               //suffix\r
+                                               String suffix = jobSpecificSettings.getProperty(Preferences.OUTPUT_SUFFIX + i);\r
+                                               if (suffix == null || suffix.equals("")) {\r
+                                                       continue;\r
+                                               }\r
+                                       }\r
+                                       BufferedWriter logWriter = this.getLogWriter(job.getJobName(), i);\r
+                                       this.executeVDub(job, i, firstValidVCF, logWriter);\r
+                                       firstValidVCF = false;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+       private void executeVDub(RecordJob job, int index, boolean firstValidVCF, BufferedWriter logWriter) throws EncoderPluginException {\r
+               String shellString = "";\r
+               Properties jobSpecificSettings = job.getEncoderPluginSettings(this);\r
+               File vcfFile = new File(jobSpecificSettings.getProperty(Preferences.VCF_PATH + index));\r
+               File sourceFile = job.getActualVideoDestination();\r
+               \r
+               String vDubBinary = this.appLayer.getPreferences().getProperty(this.getName(), Preferences.VIRTUAL_DUB_BINARY_PATH);\r
+               shellString += '"' + vDubBinary.trim() + '"';\r
+               \r
+               shellString += " /s " + '"' + vcfFile.getAbsolutePath() + '"';\r
+               \r
+               boolean clearJobControl = Boolean.valueOf(jobSpecificSettings.getProperty(Preferences.CLEAR_JOBCONTROL, "true"));\r
+               if (clearJobControl && firstValidVCF) {\r
+                       shellString += " /c";\r
+               }\r
+               \r
+               String outputFilePath = this.getOutputFilePath(job, index);\r
+               File outputFile = new File(outputFilePath);\r
+               shellString += " /p " + '"' + sourceFile.getAbsolutePath() + '"';\r
+               shellString += " " + '"' + outputFilePath + '"';\r
+               \r
+               boolean renderOutput = Boolean.valueOf(jobSpecificSettings.getProperty(Preferences.RENDER_OUTPUT, "true"));\r
+               if (renderOutput) {\r
+                       shellString += " /r";\r
+               }\r
+               \r
+               shellString += " /x";\r
+               \r
+               try {\r
+                       logWriter.write("Executing commandline: " + shellString);\r
+                       logWriter.newLine();\r
+                       File vdubDir = new File(vDubBinary).getParentFile();\r
+                       Process vDubProc;\r
+                       vDubProc = Runtime.getRuntime().exec(shellString, null, vdubDir);\r
+                       vDubProc.getOutputStream();\r
+                       InputStreamReader isr = new InputStreamReader(vDubProc.getInputStream());\r
+                       BufferedReader bufferedInputStream = new BufferedReader(isr);\r
+                       String currentLine;\r
+                       while ((currentLine = bufferedInputStream.readLine()) != null) {\r
+                               logWriter.write(currentLine);\r
+                               logWriter.newLine();\r
+                       }\r
+                       InputStreamReader isrErr = new InputStreamReader(vDubProc.getErrorStream());\r
+                       BufferedReader bufferedInputStreamErr = new BufferedReader(isrErr);\r
+                       while ((currentLine = bufferedInputStreamErr.readLine()) != null) {\r
+                               logWriter.write(currentLine);\r
+                               logWriter.newLine();\r
+                       }\r
+                       logWriter.close();\r
+                       \r
+               } catch (IOException e) {\r
+                       throw new EncoderPluginException("I/O Exception occurred when trying to execute the VDub binary or logging output", e);\r
+               }\r
+               \r
+               //extra options: replace original video with encoded one, possibly delete original one\r
+               if (Boolean.valueOf(this.appLayer.getPreferences().getProperty(this.getName(), Preferences.EXTRA_OPTIONS))) {\r
+                       String useEncStringKey = Preferences.USE_ENCODED_VIDEO + index + Preferences.USE_ENCODED_VIDEO_2;\r
+                       String useEncVideo = jobSpecificSettings.getProperty(useEncStringKey);\r
+                       File origFile = job.getActualVideoDestination();\r
+                       if (useEncVideo != null && Boolean.valueOf(useEncVideo)) {\r
+                               job.setActualVideoDestination(outputFile);\r
+                       }\r
+                       \r
+                       String deleteOrigFile = jobSpecificSettings.getProperty(Preferences.DELETE_ORIG_FILE + index);\r
+                       if (deleteOrigFile != null && Boolean.valueOf(deleteOrigFile)) {\r
+                               //only delete the original file if the encoded one exists:\r
+                               if (outputFile.exists() && outputFile.length() > 0) {\r
+                                       origFile.delete();\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+       private String getOutputFilePath(RecordJob job, int index) {\r
+               File sourceFile = job.getActualVideoDestination();\r
+               String ext = DemoRecorderUtils.getFileExtension(sourceFile);\r
+               String outputFilePath;\r
+               Properties jobSpecificSettings = job.getEncoderPluginSettings(this);\r
+               if (Boolean.valueOf(this.appLayer.getPreferences().getProperty(this.getName(), Preferences.OUTPUT_FILE_MODE))) {\r
+                       //filechooser\r
+                       outputFilePath = jobSpecificSettings.getProperty(Preferences.OUTPUT_FILE + index);\r
+               } else {\r
+                       //suffix\r
+                       outputFilePath = sourceFile.getAbsolutePath();\r
+                       String suffix = jobSpecificSettings.getProperty(Preferences.OUTPUT_SUFFIX + index);\r
+                       int idx = outputFilePath.indexOf("." + ext);\r
+                       outputFilePath = outputFilePath.substring(0, idx);\r
+                       outputFilePath += suffix + "." + ext;\r
+               }\r
+               \r
+               return outputFilePath;\r
+       }\r
+       \r
+       private BufferedWriter getLogWriter(String jobName, int vcfIndex) throws EncoderPluginException {\r
+               File logDir = DemoRecorderUtils.computeLocalFile(DemoRecorderApplication.LOGS_DIRNAME, "");\r
+               if (jobName == null || jobName.equals("")) {\r
+                       jobName = "unnamed_job";\r
+               }\r
+               String path = logDir.getAbsolutePath() + File.separator + PLUGIN_NAME + '_' + jobName + '_' + "vcf" + vcfIndex + ".log";\r
+               File logFile = new File(path);\r
+               if (!DemoRecorderUtils.attemptFileCreation(logFile)) {\r
+                       throw new EncoderPluginException("Could not create log file for VDub job at location: " + path);\r
+               }\r
+               try {\r
+                       FileWriter fileWriter = new FileWriter(logFile);\r
+                       return new BufferedWriter(fileWriter);\r
+               } catch (IOException e) {\r
+                       throw new EncoderPluginException("Could not create log file for VDub job at location: " + path, e);\r
+               }\r
+       }\r
+}\r
diff --git a/misc/tools/NexuizDemoRecorder/plugins/virtualdub/src/main/resources/META-INF/services/com.nexuiz.demorecorder.application.plugins.EncoderPlugin b/misc/tools/NexuizDemoRecorder/plugins/virtualdub/src/main/resources/META-INF/services/com.nexuiz.demorecorder.application.plugins.EncoderPlugin
new file mode 100644 (file)
index 0000000..4292f93
--- /dev/null
@@ -0,0 +1 @@
+com.nexuiz.demorecorder.application.plugins.impl.virtualdub.VirtualDubPlugin\r