1 package com.nexuiz.demorecorder.application.plugins.impl.sample;
\r
3 import java.util.Properties;
\r
5 import com.nexuiz.demorecorder.application.DemoRecorderApplication;
\r
6 import com.nexuiz.demorecorder.application.jobs.RecordJob;
\r
7 import com.nexuiz.demorecorder.application.plugins.EncoderPlugin;
\r
8 import com.nexuiz.demorecorder.application.plugins.EncoderPluginException;
\r
11 * This is a sample plug-in implementation. It does not really do anything, but it
\r
12 * is supposed to show you how to implement a plug-in and where to do what.
\r
14 * First of all, it is important that your final jar file (you can have Maven create
\r
15 * it for you) contains the META-INF folder (it will have that one anyway), and within
\r
16 * that folder you must have the folder "services", in which you must have a file called
\r
17 * com.nexuiz.demorecorder.application.plugins.EncoderPlugin (this is the fully
\r
18 * qualified name of the interface you need to implement, EncoderPlugin).
\r
19 * This file needs to contain just one line: the fully qualified name to your
\r
20 * implementation class!
\r
22 * Okay. The Nexuiz Demo Recorder (NDR) gives your plug-in 2 kinds of possibilities to
\r
23 * configure it ("set it up") from within the NDR. Configuring the plug-in is also
\r
24 * referred to as "setting preferences". There are
\r
25 * - Global preferences: these will be shown in the "Preferences" dialog of the NDR
\r
26 * - Job-specific preferences: these will be shown in the dialog you get when creating
\r
27 * new jobs or templates, or when editing them
\r
29 * Once the NDR loaded your plug-in, the first thing it will do is to call
\r
30 * setApplicationLayer(), handing your plug-in the reference to the app-layer. Make sure that
\r
31 * you save it in a private member variable!
\r
33 * NDR will ask your plug-in to tell it about its global and job-specific preferences that exist.
\r
34 * For each of these 2 kinds of preferences it will also ask you for the order in which you want
\r
35 * these settings to appear in dialogs.
\r
37 * The methods that ask you to return a Properties object: create a new Properties object and fill
\r
38 * it with KEYS (that identify the setting), and VALUES (reasonable default values). The app-layer
\r
39 * will save these "new" settings in the app_preferences.xml in the "settings" folder once NDR
\r
40 * is closed (this applies only to the global settings!). That just means that, later on, to figure
\r
41 * out whether the user changed settings from their default value, you need to ask the app-layer
\r
42 * for its preferences object (that might have been manipulated by the user using the GUI) and look
\r
43 * for "your" settings in that Properties object. A good example is the isEnabled() method.
\r
45 public class SamplePlugin implements EncoderPlugin {
\r
48 * Do not put the word "plug-in" in here, that would be redundant.
\r
50 private static final String PLUGIN_NAME = "Sample";
\r
53 * Here we store our preferences. It is not necessary that these are in a inner-class, do it in
\r
54 * your way if you want.
\r
56 private static class Preferences {
\r
58 * Lets start with GLOBAL settings which will be seen in the Preferences dialog of the NDR
\r
60 public static final String ENABLED = "Enabled"; //we will need this! "Enabled" means that
\r
61 //that the preferences dialog will show the exact word "Enabled"
\r
63 public static final String SAMPLE_SETTING = "Some sample setting";
\r
66 * Now we define the order in which we want these to be shown.
\r
68 public static final String[] GLOBAL_PREFERENCES_ORDER = {
\r
73 //job-specific preferences
\r
74 public static final String IN_USE_FOR_THIS_JOB = "Do something for this job";
\r
77 * OK, so far we have actually only created labels. But we also need default values
\r
78 * So let's have a function that sets the default values up.
\r
80 public static Properties globalDefaultPreferences = new Properties();
\r
81 public static void createPreferenceDefaultValues() {
\r
82 globalDefaultPreferences.setProperty(ENABLED, "false");
\r
83 globalDefaultPreferences.setProperty(SAMPLE_SETTING, "filechooser");
\r
85 * Note that the values for the defaults can be:
\r
86 * - "true" or "false", in this case the GUI will show a check-box
\r
87 * - "filechooser", in this case the GUI will show a button that allows the user to select
\r
89 * - anything else (also empty string if you like): will show a text field in the GUI
\r
90 * (you are in charge of parsing it)
\r
96 private DemoRecorderApplication appLayer;
\r
99 * You must only have a default constructor without parameters!
\r
101 public SamplePlugin() {
\r
102 Preferences.createPreferenceDefaultValues();
\r
108 public Properties getGlobalPreferences() {
\r
109 return Preferences.globalDefaultPreferences;
\r
113 public String[] getGlobalPreferencesOrder() {
\r
114 return Preferences.GLOBAL_PREFERENCES_ORDER;
\r
118 public Properties getJobSpecificPreferences() {
\r
120 * This method is called whenever the dialog to create new jobs/templates (or edit them)
\r
121 * is opened. This means that you can dynamically create the returned Properties object
\r
122 * if you like, or you could of course also return something static.
\r
124 Properties preferences = new Properties();
\r
125 preferences.setProperty(Preferences.IN_USE_FOR_THIS_JOB, "true");
\r
126 return preferences;
\r
130 public String[] getJobSpecificPreferencesOrder() {
\r
131 String[] order = {Preferences.IN_USE_FOR_THIS_JOB};
\r
136 public String getName() {
\r
137 return PLUGIN_NAME;
\r
141 public void setApplicationLayer(DemoRecorderApplication appLayer) {
\r
142 this.appLayer = appLayer;
\r
146 public boolean isEnabled() {
\r
148 * Here we get the Properties object of the app-layer. Notice that this is actually a
\r
149 * NDRPreferences object. It has a new method getProperty(String category, String key).
\r
150 * The category is the name of our plug-in. The key is obviously our own ENABLED key.
\r
152 String enabledString = this.appLayer.getPreferences().getProperty(PLUGIN_NAME, Preferences.ENABLED);
\r
153 return Boolean.valueOf(enabledString);
\r
157 public void executeEncoder(RecordJob job) throws EncoderPluginException {
\r
159 * This is where the party gets started.
\r
160 * Of course you need to check whether your plug-in is enabled by the user, and whether the
\r
161 * job-specific settings are set correctly. So let's do this now:
\r
163 if (!this.isEnabled()) {
\r
167 if (job.getActualVideoDestination() == null) {
\r
168 //should never happen... but just to make sure!
\r
169 throw new EncoderPluginException("Actual video destination is not set (should have been set when processing the job)");
\r
172 if (!job.getActualVideoDestination().exists()) {
\r
173 throw new EncoderPluginException("Could not locate recorded video file (source) at location "
\r
174 + job.getActualVideoDestination().getAbsolutePath());
\r
177 //check for a job-specific setting ... this time we need it from the job:
\r
178 Properties jobSpecificSettings = job.getEncoderPluginSettings(this);
\r
179 String isEnabled = jobSpecificSettings.getProperty(Preferences.IN_USE_FOR_THIS_JOB);
\r
180 if (!Boolean.valueOf(isEnabled)) {
\r
181 //the job does not want our plug-in to be executed, d'oh
\r
182 throw new EncoderPluginException("We are not enabled to do anything for this job :-(");
\r
183 //of course in a real implementation, instead of throwing an exception we'd just "return;"
\r
187 * Now we can start doing the work. What you'll normally do is to construct a big string that you then have executed
\r
188 * Have a look at the VirtualDub plug-in implementation to see how I did it.
\r
190 * IMPORTANT: unless you parse the output of the console when executing a shell command (to check whether
\r
191 * the encoder threw error messages at you), it is recommended that you create a log file of each job.
\r
192 * The VirtualDub plug-in also provides an example of how to do that.
\r
194 * Also notice the use of the EncoderPluginException. Whenever something goes wrong, throw this exception.
\r
195 * Note that there is also another constructor EncoderPluginException(String message, Throwable t) where you
\r
196 * can attach the original exception.
\r