Plex Media Center for OS X Leopard

9. Site Configurations

9.1. Overview

A Site Configuration file allows a Flash or Silverlight player to be played within a web browser.

Pretend the you could fire up a web browser, go to your favorite video site and draw a rectangle around just the video player. The video player would then be zoomed in to fill the screen and all of other web page junk is just thrown away so that you can watch the video without any distractions.

Site Configurations are complements to WebVideoItem() in the plugin framework. They act as handlers to the urls that the WebVideoItem() passes out.

9.1.1. When you should NOT create a Site Config

If you have access to the video stream directly, then you should not use a site configuration file.

You will have to do some sleuthing to see if you can get access to the .flv, .mp4 or RTMP streams directly. You can use tools like the Net inspector in Firebug or you can sometimes find the stream URL passed in as a parameter to the player if you view the HTML source.

Some formats will just not work. RTMPE (note the E) or other formats which have DRM will have to be played with the flash/silverlight player and warrant the creation of a Site Configuration file

9.1.2. Where to put them

Site configurations can go one of two places.

  1. (recommended) Inside of your plugin bundle file MyPlugin.bundle/Contents/Site Configurations/yourfile.xml
  2. ~/Library/Application Support/Plex Media Server/Site Configurations/yourfile.xml

9.2. Gathering Player Information

When creating site configs, often you will need to have access to information such as:

  1. Url’s of the webpage / player
  2. Height and Width of the video player
  3. X/Y coordinates of buttons on the player
  4. X/Y coordinates of other elements / colors on the screen

You’ll use this information later on to do things like “click on a button” or “find out what color the pixel is here”

This information can be a real pain to get without some tools and techniques to help you out. Here are just a few.

9.2.1. URLs

You will need two urls saved away somewhere for future reference. Later on, you will use these URLs in order to create two regular expressions for the <site> tag

The first URL you will need is the URL of the page which contains the Flash or Silverlight player. You can simply copy and paste the URL from your browser URL bar.

The other URL you will need is the URL of the Flash or Silverlight player. You can use the “View Source” function of your web browser and then search for the URL that is used in the <embed> tag for the plugin.

Now that you have these URL’s save them away in a text file for later use.

9.2.2. Player Size and Coordinates

Firebug

Install Firebug for Firefox and then simply visit the webpage containing the video player.

From here, (1) open Firebug and (2) click on the “Inspect” icon and then click on the (3) flash player in the page.

Information about this element list CSS style information now shows on the right hand side. Click on the (4) “Layout” tab over on the right.

You should now see (5) height and width information for the selected element on the page.

_images/firefox-firebug-size-example.png

Free Ruler

Another excellent tool to use (OSX) is called Free Ruler.

Download and install this program and you will be able to overlay the horizontal and vertical rulers over the top/left edge of the flash player. With FreeRuler in the foreground, you’ll be able to hit Command-C to copy the x/y coordinates of the current mouse position so that you can use this information later on with tags such as <click> and <move>.

9.2.3. Colors

You can use the DigitlColor Meter tool which comes with OSX to find out the hex color value of any pixel on the screen.

9.3. The XML File

9.3.1. The <site> Element

Site configuration files all start out with the <site> tag along with the proper <xml? .. definition. A bare bones example looks like so:

<site  site="http://www.southparkstudios.com/episodes"
       plugin="http://media.mtvnservices.com/mgid.*southparkstudios.com"
       initialState="playing"
       version="1.0">

       <!-- ... -->

</site>

The site and plugin attributes are actually regular expressions which match URL’s

The site regular expression must match the URL for the webpage which contains the flash or silverlight plugin. This regular expression is scanned whenever a WebVideoItem url is played.

If another site configuration file has a url which also matches the url, then the regular expression which is the most specific (longer) wins and the site configuration file containing that regular expression is run.

The plugin regular expression must match the url for the embedded player. This URL is usually found in the <embed> tag of the web page.

The initialState attribute tells the player to begin the the <state> tag with the corresponding name attribute. More on States and Events

9.3.2. Seekbars

A seekbar is a representation of your progress through a video. It shows you information such as:

  1. How far through the video you are
  2. Control for skip forward / skip backward

Some seekbars are graphical in nature only. For these, use the ‘simple’ or ‘thumb’ value for the type attribute on the <seekbar> tag.

Some Flash/Silverlight players expose hooks in their players which allow javascript to actually control and retrieve information from the player. This is an advanced topic and you would use ‘javascript’ for the type attribute on the <seekbar> tag.

9.3.2.1. Simple

This is a seekbar which shows progrss as a bar going from left to right across the player. It does NOT have a “thumb” for you to grab/drag in order to skip to a different place in the video.

Here is an example:

<seekbar type="simple">
  <start x="63" y="290" />
  <end x="388" y="290" />
  <played>
    <color rgb="4f4f4f" />
    <color rgb="616161" />
    </played>
</seekbar>

This example says the following in plain english.

The seekbar on this player starts at (63,290) and ends at (388,290). These coordinates are not relative to the actual web page, but of the actual flash/silverlight player. We create a line created by “drawing” from <start> to <end>. If, under this line, we see pixels colored #4f4f4f or #616161, then we’ll consider that portion played. Once we find a color that does NOT match, we’ll stop looking.

The site config then does the math for the portion of played / unplayed and now knows how to do a few things:

  1. where to click the mouse when you skip ahead or skip back
  2. how to update the progress bar in Plex

9.3.2.2. Thumb

This is a seekbar which has a “thumb” for you to grab and drag around to set the position of the video. It is very similar to a ‘simple’ seekbar but the way the colors are interpreted is a litte different.

Here is an example:

<seekbar type="thumb">
 <start x="63" y="290" />
 <end x="388" y="290" />
 <played>
    <color rgb="d3d3d3" />
 </played>
</seekbar>

This example says the following in plain english.

The seekbar on this player starts at (63,290) and ends at (388,290). These coordinates are not relative to the actual web page, but of the actual flash/silverlight player. We create a line created by “drawing” from <start> to <end>. If, under this line we see the color #d3d3d3, then we immediately stop and record that position as the current playing position.

9.3.2.3. Javascript

As mentioned above, some video players have exposed javascript API’s for their video players. For those sites that have done this, you can access the values from those functions and pass them back over to Plex.

<seekbar type="javascript">
  <percentComplete equals="$.currentTime()/$.duration() * 100.0" />
  <bigStep minus="$.seek($.currentTime() - 30)" plus="$.seek($.currentTime() + 30)" />
  <smallStep minus="$.seek($.currentTime() - 10)" plus="$.seek($.currentTime() + 10)" />
  <end condition="$.currentTime() > 0 &amp;&amp; $.currentTime() > $.duration()" />
</seekbar>

There are a few things that should be mentioned about the example above.

First, you’ll notice the $ variable. This is a special variable that Plex creates when the page is loaded. It is equal to the DOM node of the flash player which was identified when the site configuration file was loaded.

It is somewhat equivalant to Plex having done this for you where the element in question is the actual embeded SWF file:

$ = document.getElementById(...)

9.3.3. States and Events

The web video player allows you to define states of being as well as events and actions that are valid during those states.

You will be using events to detect a change and you’ll then take “action”. Taking action typically involves also moving into another state, which is aware of other events and actions.

We’ll go into detail about the <action> and <event> tags later on but here are a few examples of the terms ‘state’, ‘event’ and ‘action’

Examples of states:

  1. Playing the video
  2. Video is paused
  3. An Ad is playing
  4. Video is buffereing
  5. Video is done playing

Examples of events:

  1. User pressed the button named pause
  2. Noticed a certain color or colors somewhere on the screen

Examples of actions:

  1. Click a button
  2. Move to another state

Lets take a look at a full example:

<site  site="http://www.southparkstudios.com/episodes"
       plugin="http://media.mtvnservices.com/mgid.*southparkstudios.com"
       initialState="playing"
       version="1.0">
 <!-- PLAYING -->
 <state name="playing">
  <event>
   <condition>
    <command name="pause" />
   </condition>
   <action>
    <click x="15" y="304" />
    <goto state="paused" />
   </action>
  </event>
 </state>
 <!-- PAUSED -->
 <state name="paused">
  <event>
   <condition>
    <command name="play" />
   </condition>
   <action>
    <click x="15" y="304" />
    <goto state="playing" />
   </action>
  </event>
 </state>
</site>

Here is what this file is saying.

We’ve found a SWF file and we are going to enter the initial state with the name of “playing”. If the user causes the command named “pause” to run (could be keyboard, mouse, remote control etc), then we’re going to click on the screen at (15,304) and then go to the “paused” state. Then the user runs the command named “play” and we’ll click on (15,304) again and then enter the “playing” state.

Note that the name attribute of the <state> tag doesn’t inherently mean anything. It is simply a label so that we can <goto> it and reference it with initialState. We could have called the “playing” state “foo” and the . Plex Media Server does not care.

The “play” in <command> tag DOES matter but we will dive into that later.

Each state may have 0 or more <event> tags.

9.3.3.1. Event Conditions

Each <event> tag has one <condition> tag and one <action> tag inside.

Conditions are then built up through a combination of logic tags and conditionals. Specifics on the usage of each tag is detailed in the documentation for each tag individually.

Logic Tags:

Conditional Tags:

Example:

<state name="playing">
 <event>
  <condition>
   <and> <!-- logic tag -->
     <command name="pause" /> <!-- conditional -->
     <or> <!-- logic tag -->
       <color x="45" y="45" rgb="ffffff"/> <!-- conditional -->
       <color x="46" y="45" rgb="ffffff"/> <!-- conditional -->
     </or>
   </and>
  </condition>
  <action>
   <click x="15" y="304" />
   <goto state="paused" />
  </action>
 </event>
</state>

9.3.3.2. Event Actions

As mentioned previously, each <event> tag has one <condition> tag and one <action> tag inside.

These <action> tags can then have one or more actions as children. They are executed in the order that they are defined from top to bottom.

Specifics on the usage of each action is detailed in the documentation for each tag individually.

Action Tags:

9.3.4. Named Condition Definitions

The <condition> tag is used in one of two ways. As an event condition (see: Event Conditions) or in this case, as a definition of a named condition which can be called out and used in event conditions.

Think of these as condition “functions” that can be re-used in more than one <state>.

The following example defined a named conditional, ‘buffering_colors_showing’ and then calls out to that condition later on in the “playing” state:

<site  site="http://www.southparkstudios.com/episodes"
       plugin="http://media.mtvnservices.com/mgid.*southparkstudios.com"
       initialState="playing"
       version="1.0">

 <!-- NAMED CONDITIONAL DEFINITION -->
 <condition name="buffering_colors_showing">
   <and>
     <color x="1" y="1" rgb="ffffff"/>
     <color x="2" y="2" rgb="ffffff"/>
   </and>
 </condition>

 <state name="playing">
  <event>
   <condition>
    <and>
       <command name="pause" />
       <not>
         <condition name="buffering_colors_showing"/>
       </not>
    </and>
   </condition>
   <action>
    <click x="15" y="304" />
    <goto state="paused" />
   </action>
  </event>
 </state>

 <!-- ... -->

</site>

As you can see, this can make for powerful condition reuse especially when you combine named conditions with logic tags such as <or>.

9.3.5. Advanced

9.3.5.1. User Agents

Some sites have strange user agent requirements or block requests based on the user agent.

You can specify a user agent using the agent attribute of the <site> tag.

You can randomize the user agent by setting randomAgent to true in the <site> tag.

TODO: what is the default user agent?

9.3.5.2. Access to Preferences

There are several ways you can use preferences.

In conditionals, you can test to see if a preference key exists by using the <pref> conditional tag like so:

<condition>
  <pref name="username" exists="true"/>
</condition>

The value of preference variables are also available for use in other tags as well. For instance, when filling out a form in the site config, you can type the value of a pref using the <type> tag like so:

<type text="${username}"/>

You can also use preference variable replacements in javascript expressions and several other places like so:

<run script="doLogin(${username},${password});"/>

Preference variable replacement works in the following elements/attributes:

  1. <setCookie> value attribute
  2. <run> script attribute
  3. <type> text attribute
  4. <smallStep> plus and minus attributes
  5. <bigStep> plus and minus attributes
  6. <end> condition attribute
  7. <javascript> script attribute

Changed in version Plex: 0.8.3 <setCookie> value attribute can accept javascript

Changed in version Plex: 0.8.3 <javascript> script attribute can accept javascript

9.3.5.3. Setting Cookies

You can set cookies for plugins too! Just take a look at the <setCookie> tag documentation for more details.

9.3.5.4. Filling Out Forms

This can be tricky and you’ll need to use a combination of techniques to do this including detecting if a form is present, clicking on form elements, filling them in etc.

here is an example from the mlb.xml site configuration file:

<!-- login prompt -->
<state name="login">
  <event>
    <condition>
      <and>
        <condition name="prompting-for-login"/>
        <pref name="login" exists="true"/>
        <pref name="password" exists="true"/>
      </and>
    </condition>
    <action>
      <!-- set focus -->
      <click x="116" y="409"/>
      <pause time="10"/>

      <!-- "double click" the email input to select all -->
      <click x="116" y="409"/>
      <click x="116" y="409"/>
      <pause time="100"/>
      <type text="${login}"/>

      <!-- click the password input -->
      <pause time="10"/>
      <click x="116" y="439"/>
      <pause time="100"/>
      <type text="${password}"/>

      <!-- submit the form -->
      <pause time="100"/>
      <type key="13"/>

      <!-- wait for the form to animate closed -->
      <pause time="2000"/>

      <goto state="playing"/>
    </action>
  </event>
</state>

9.3.5.5. Javascript Execution

Javascript can be run in two places.

Actions

If you would like to run javascript inside of an action, you’ll need to use the <run> tag.

ex.

<run script="myVariable=10;"/>

See the syntax for the <run> tag for more details.

Conditions

If you would like to test a javascript expression for truth inside of a <condition>, then you’ll need to use the <javascript> tag.

example assuming myVariable is 10 :

<javascript script="myVariable" matches="10"/> <!-- true condition -->
<javascript script="myVariable == 10 ? 1 : 0" matches="1"/> <!-- true condition -->
<javascript script="myVariable == 99 ? 1 : 0" matches="1"/> <!-- false condition -->

9.4. Reference

9.4.1. Tags (Alphabetical)

9.4.1.1. <action>

<!ELEMENT action (click|goto|lockPlugin|move|pause|run|type|visit)*>

The <action> elemement is used inside a state and event element and tells the player “what do to” when it’s corresponding condition is true.

eg.

<state name="playing">
  <event>
      <condition>
          <command name="pause"/>
      </condition>
      <action>
          <goto state="paused"/>
      </action>
  </event>
</state>

Here is a list of action tags:

9.4.1.2. <and>

<!ELEMENT and (and|color|command|condition|frameLoaded|javascript|not|or|pref|title|url)+>

This element is used inside of <condition> tags to build out boolean logic.

Unlike the <condition> and <not> tags, the <and> tag may have more than one of any operator/conditional.

See also:

ex.

<condition name="foo">
  <and>
    <or>
        <color x="1" y="1" rgb="ffffff"/>
        <color x="2" y="2" rgb="ffffff"/>
    </or>
    <not>
      <color x="3" y="3" rgb="ffffff"/>
    </not>
    <color x="4" y="4" rgb="ffffff"/>
  </and>
</condition>

9.4.1.3. <bigStep>

<!ELEMENT bigStep EMPTY>
<!ATTLIST bigStep minus CDATA #REQUIRED>
<!ATTLIST bigStep plus CDATA #REQUIRED>

This is only used in Javascript seekbars. It defines two javascript expressions to be executed.

One when big stepping forward and one backwards.

ex.

<bigStep plus="myPlayerObj.skipForward(10);" minus="myPlayerObj.skipBackward(10);"/>

Both the minus and plus attributes may also contain a preference based replacement variable. For example, the following code would replace ${mystepsize} with the value of the preference named mystepsize:

<bigStep plus="myPlayerObj.skipForward(${mystepsize});" minus="myPlayerObj.skipBackward(${mystepsize});"/>

9.4.1.4. <condition>

<!ELEMENT condition (and|color|command|condition|frameLoaded|javascript|not|or|pref|title|url)?>
<!ATTLIST condition name CDATA #IMPLIED>

The condition tag can be a child of either the <site> tag or the <event> tag.

When directly under the <site> tag it is acting as a named conditional block. See: Named Condition Definitions

When under the <event> tag it is acting as an inline definition. See: Event Conditions

The <condition> tag may only have one (or none) of either an operator (and, or, not) or a condition tag (color, command, condition, frameLoaded, javascript, pref, title, url)

9.4.1.5. <color>

<!ELEMENT color EMPTY>
<!ATTLIST color x CDATA "0">
<!ATTLIST color y CDATA "0">
<!ATTLIST color rgb CDATA #IMPLIED>
<!ATTLIST color op (dimmer-than|brighter-than) #IMPLIED>

This condition allows you to test pixel colors underneath a specific x and y coordinate. X/Y coordinates are relative to the size of the player and not the entire web page. Negative (relative) coordinates are allowed.

The rgb attribute is in the hex RGB value. It should not include the ‘#’ symbol nor should it be abbreviated as it can be in CSS.

eg:

rgb="FFFFFF"  - ok
rgb="#FFFFFF" - no
rgb="#FFF"    - no
rgb="FFF"     - no

If the op attribute is omitted, then the operation is equality. Otherwise the rgb value is used as reference for brighter-than or dimmer-than

9.4.1.6. <click>

<!ELEMENT click EMPTY>
<!ATTLIST click x CDATA #REQUIRED>
<!ATTLIST click y CDATA #REQUIRED>
<!ATTLIST click skipMouseUp (true|false) "false">

This condition allows you to click at a specific x and y coordinate. X/Y coordinates are relative to the size of the player and not the entire web page. Negative (relative) coordinates are allowed.

If you do not want a mouse up event to be fired, then set the skipMouseUp attribute to true.

9.4.1.7. <command>

<!ELEMENT command EMPTY>
<!ATTLIST command name CDATA #REQUIRED> <!-- pause|play|bigstep+|smallstep+|bigstep-|smallstep-|chapter+|chapter- -->

This condition can be used to test for Plex video player events. These occur in response to the keyboard, mouse or remote control.

Valid values for the name attribute are:

  • pause
  • play
  • bigstep+
  • bigstep-
  • smallstep+
  • smallstep-
  • chapter+
  • chapter-

9.4.1.8. <crop>

<!ELEMENT crop EMPTY>
<!ATTLIST crop x CDATA #REQUIRED>
<!ATTLIST crop y CDATA #REQUIRED>
<!ATTLIST crop width CDATA #REQUIRED>
<!ATTLIST crop height CDATA #REQUIRED>

This tag is used to crop the video player. Usually it’s used to chop out blank space and or some player control so that the screen it zoomed in to focus soley on the video content.

If the player has extra data that you would like to crop out you can note the pixel width and height that you wish to crop from the top (y) and left (x). To crop from the right or bottom just reduce the width and height attributes.

If width and height are set to 0, then they are considered “auto” and will not crop the right or bottom.

9.4.1.9. <dead>

<!ELEMENT dead EMPTY>
<!ATTLIST dead x CDATA "0">
<!ATTLIST dead y CDATA "0">

Used in seekbars. This is the x/y coordinate where you would like the mouse to rest after clicking on a position in the seekbar. Sometimes a players controls need to fade back out and you need to put the mouse in a “safe” place.

9.4.1.10. <end>

<!ELEMENT end EMPTY>
<!ATTLIST end x CDATA "0">
<!ATTLIST end y CDATA "0">
<!ATTLIST end condition CDATA #IMPLIED>

For Simple and Thumb seekbars you should specify the x/y coordinates of the end of the playback timeline indicator.

For Javascript seekbars, you should specify the condition attribute with a javascript expression evaluating to true if the player is at the “end”

In the case of Javascript seekbars, the condition attribute may also contain a preference based replacement variable. For example, the following code would replace ${username} with the value of the preference named username:

<end condition="${username} == 'david'">

See: Seekbars

9.4.1.11. <event>

<!ELEMENT event (condition,action)>

A container who’s parent is the <state> and that contains a <condition> and a <action> tag.

See: States and Events

9.4.1.12. <frameLoaded>

<!ELEMENT frameLoaded EMPTY>

A condition which evaluates as true when the webpage has been loaded.

9.4.1.13. <goto>

<!ELEMENT goto EMPTY>
<!ATTLIST goto state CDATA #REQUIRED>
<!ATTLIST goto param CDATA #IMPLIED>

An action which will transition to the state specified in the state attribute

If the state attribute is “end” it is handled specially and will exit the video and return to the previous navigation menu in Plex. Addiionally, if you provide some text to the param attribute when transitioning to the “end” state, then this message will be displayed in a message box to the user. Useful for error messages when exiting.

9.4.1.14. <javascript>

Changed in version Plex: 0.8.3 <javascript> script attribute can accept javascript replacement

<!ELEMENT javascript EMPTY>
<!ATTLIST javascript script CDATA #REQUIRED>
<!ATTLIST javascript matches CDATA #REQUIRED>

This condition takes a javascript expression in the script attribute and an value to compare the expression to in the matches attribute.

Examples assuming myVariable is 10 :

<javascript script="myVariable" matches="10"/> <!-- true condition -->
<javascript script="myVariable == 10 ? 1 : 0" matches="1"/> <!-- true condition -->
<javascript script="myVariable == 99 ? 1 : 0" matches="1"/> <!-- false condition -->

9.4.1.15. <lockPlugin>

<!ELEMENT lockPlugin EMPTY>

This is only relevant if you have also set the manualLock attribue to true in the <site> tag.

You should only use the combination of manualLock / lockPlugin if you have to perform actions/conditions prior to getting to the video itself. For example, logging in, changing the size of the player with javascript, or setting a cookie and redirecting to another url etc.

9.4.1.16. <move>

<!ELEMENT move EMPTY>
<!ATTLIST move x CDATA #REQUIRED>
<!ATTLIST move y CDATA #REQUIRED>

This condition allows you to move the mouse to a specific x and y coordinate. X/Y coordinates are relative to the size of the player and not the entire web page. Negative (relative) coordinates are allowed.

9.4.1.17. <not>

<!ELEMENT not (and|color|command|condition|frameLoaded|javascript|not|or|pref|title|url)>

This element is used inside of <condition> tags to build out boolean logic.

The <not> tag must have one and only one of either an operator (and, or, not) or a condition tag (color, command, condition, frameLoaded, javascript, pref, title, url)

See also:

ex.

<condition name="foo">
  <and>
    <or>
    <color x="1" y="1" rgb="ffffff"/>
    <color x="2" y="2" rgb="ffffff"/>
    </or>
    <not>
      <color x="3" y="3" rgb="ffffff"/>
    </not>
    <color x="4" y="4" rgb="ffffff"/>
  </and>
</condition>

9.4.1.18. <or>

<!ELEMENT or (and|color|command|condition|frameLoaded|javascript|not|or|pref|title|url)+>

This element is used inside of <condition> tags to build out boolean logic.

Unlike the <condition> and <not> tags, the <or> tag may have more than one of any operator/conditional.

See also:

ex.

<condition name="foo">
<and>
 <or>
     <color x="1" y="1" rgb="ffffff"/>
     <color x="2" y="2" rgb="ffffff"/>
 </or>
 <not>
   <color x="3" y="3" rgb="ffffff"/>
 </not>
 <color x="4" y="4" rgb="ffffff"/>
</and>
</condition>

9.4.1.19. <pause>

<!ELEMENT pause EMPTY>
<!ATTLIST pause time CDATA "0"> <!-- number of milliseconds to wait -->

An action which will wait for the specified number of milliseconds.

ex.

<pause time="1000"/> <!-- wait one second -->

9.4.1.20. <percentComplete>

<!ELEMENT percentComplete EMPTY>
<!ATTLIST percentComplete equals CDATA #REQUIRED>

This is only used in Javascript seekbars. It defines a single javascript expression which should evaluate to floating point number between 0.0 and 100.0.

ex.

<percentComplete equals="(myPlayerObj.position() / myPlayerObj.vidLength()) * 100.0"/>

The equals attribute may also be a preference based replacement variable. For example, ${vidlength} would be replaced by the value of the preference named vidlength

<percentComplete equals="(myPlayerObj.position() / ${vidlength}) * 100.0"/>

9.4.1.21. <played>

<!ELEMENT played (color|condition)*>

The color(s) representing the played portion of the Seekbar (for simple seekbars) or the color(s) that should match the Seekbar thumb (for thumb seekbars)

Only used in Simple and Thumb seekbars

9.4.1.22. <pre>

<!ELEMENT pre EMPTY>
<!ATTLIST pre m CDATA #REQUIRED>

TODO: what exactly is this and how should it be used? Prerequisites too like does it require manualLock=True etc.

9.4.1.23. <pref>

<!ELEMENT pref EMPTY>
<!ATTLIST pref name CDATA #REQUIRED>
<!ATTLIST pref exists (true|false) "false">

A condition to test for the presence or absense of a preference.

ex.

<pref name="username" exists="true"/>

9.4.1.24. <run>

<!ELEMENT run EMPTY>
<!ATTLIST run script CDATA #REQUIRED>

An action to run the specified javascript.

ex.

<run script="myVariable=10;"/>

The script attribute may also contain a preference based replacement variable. For example:

<run script="myUsername=${username}"/>

9.4.1.25. <seekbar>

<!ELEMENT seekbar (start?|end?|played?|dead?|bigStep?|smallStep?|percentComplete?)*>
<!ATTLIST seekbar type (javascript|simple|thumb) #REQUIRED>

The container for seekbars. See Seekbars for more information.

9.4.1.26. <setCookie>

Changed in version Plex: 0.8.3 <setCookie> value attribute can accept javascript replacement

<!ELEMENT setCookie EMPTY>
<!ATTLIST setCookie domain CDATA #IMPLIED>
<!ATTLIST setCookie path CDATA #IMPLIED>
<!ATTLIST setCookie name CDATA #IMPLIED>
<!ATTLIST setCookie secure CDATA #IMPLIED>
<!ATTLIST setCookie value CDATA #IMPLIED>

Allows you to set a cookie.

ex.

<site>
  <setCookie domain=".videosite.com" path="/" name="tosAccepted" value="true" secure="false"/>
  <!-- ... -->
</site>

9.4.1.27. <site>

<!ELEMENT site (condition|crop|pre|seekbar|setCookie|state)*>
<!ATTLIST site agent CDATA #IMPLIED>
<!ATTLIST site allowPopups (true|false) "false">
<!ATTLIST site identifier CDATA #IMPLIED>
<!ATTLIST site initialState CDATA #REQUIRED>
<!ATTLIST site manualLock (true|false) "false">
<!ATTLIST site plugin CDATA #IMPLIED>
<!ATTLIST site randomAgent (true|false) "false">
<!ATTLIST site site CDATA #REQUIRED>
<!ATTLIST site version CDATA "1.0">
<!ATTLIST site windowHeight CDATA #IMPLIED>
<!ATTLIST site windowWidth CDATA #IMPLIED>

9.4.1.28. <start>

<!ELEMENT start EMPTY>
<!ATTLIST start x CDATA "0">
<!ATTLIST start y CDATA "0">

The x/y coordinates of the end of the playback timeline indicator.

Only used in Simple and Thumb seekbars

See: Seekbars

9.4.1.29. <state>

<!ELEMENT state (event)*>
<!ATTLIST state name CDATA #REQUIRED>

A state contains one or more <event> tags each of which contain a <condition> and an <action>.

Typically, in an action a <goto> tag is used with a name to transition to another state with the corresponding state attribute set.

See States and Events for more information

9.4.1.30. <smallStep>

<!ELEMENT smallStep EMPTY>
<!ATTLIST smallStep minus CDATA #REQUIRED>
<!ATTLIST smallStep plus CDATA #REQUIRED>

This is only used in Javascript seekbars. It defines two javascript expressions to be executed.

One when big stepping forward and one backwards.

ex.

<smallStep plus="myPlayerObj.skipForward(5);" minus="myPlayerObj.skipBackward(5);"/>

Both the minus and plus attributes may also contain a preference based replacement variable. For example, the following code would replace ${mystepsize} with the value of the preference named mystepsize:

<smallStep plus="myPlayerObj.skipForward(${mystepsize});" minus="myPlayerObj.skipBackward(${mystepsize});"/>

9.4.1.31. <title>

<!ELEMENT title EMPTY>
<!ATTLIST title matches CDATA #REQUIRED>

A condition which evaluates to true when the title of the webpage matches the regular expression in matches.

9.4.1.32. <type>

<!ELEMENT type EMPTY>
<!ATTLIST type text CDATA #IMPLIED>
<!ATTLIST type key CDATA #IMPLIED>

An action to either type a string or a single key code.

You may use text or key but not both together.

The text attribute may also be a preference based replacement variable. For example, the following code block would type out the characters that are contained in the value for the username preference :

<type text="${username}"/>

9.4.1.33. <url>

<!ELEMENT url EMPTY>
<!ATTLIST url matches CDATA #REQUIRED>

A condition which evaluates to true when the url of the webpage matches the regular expression in matches.

9.4.1.34. <visit>

<!ELEMENT visit EMPTY>
<!ATTLIST visit url CDATA #REQUIRED>

An action which causes the url specified in url to be visited.

9.4.2. XML DTD

Download the DTD

<!-- ROOT -->
<!ELEMENT site (condition|crop|pre|seekbar|setCookie|state)*>
<!ATTLIST site allowPopups (true|false) "false">
<!ATTLIST site identifier CDATA #IMPLIED>
<!ATTLIST site initialState CDATA #REQUIRED>
<!ATTLIST site manualLock (true|false) "false">
<!ATTLIST site plugin CDATA #IMPLIED>
<!ATTLIST site randomAgent (true|false) "false">
<!ATTLIST site site CDATA #REQUIRED>
<!ATTLIST site version CDATA "1.0">
<!ATTLIST site windowHeight CDATA #IMPLIED>
<!ATTLIST site windowWidth CDATA #IMPLIED>
<!ATTLIST site agent CDATA #IMPLIED>

<!-- CORE STRUCTURE -->

<!ELEMENT action (click|goto|lockPlugin|move|pause|run|type|visit)*>

<!ELEMENT condition (and|color|command|condition|frameLoaded|javascript|not|or|pref|title|url)?>
<!ATTLIST condition name CDATA #IMPLIED>

<!ELEMENT event (condition,action)>

<!ELEMENT state (event)*>
<!ATTLIST state name CDATA #REQUIRED>

<!-- SEEKBAR / PLAYER SIZE -->

<!ELEMENT seekbar (start?|end?|played?|dead?|bigStep?|smallStep?|percentComplete?)*>
<!ATTLIST seekbar type (javascript|simple|thumb) #REQUIRED>

<!ELEMENT start EMPTY>
<!ATTLIST start x CDATA "0">
<!ATTLIST start y CDATA "0">

<!ELEMENT end EMPTY>
<!ATTLIST end x CDATA "0">
<!ATTLIST end y CDATA "0">
<!ATTLIST end condition CDATA #IMPLIED>

<!ELEMENT played (color|condition)*>

<!ELEMENT dead EMPTY>
<!ATTLIST dead x CDATA "0">
<!ATTLIST dead y CDATA "0">

<!-- javascript seekbar stuff -->
<!ELEMENT bigStep EMPTY>
<!ATTLIST bigStep minus CDATA #REQUIRED>
<!ATTLIST bigStep plus CDATA #REQUIRED>

<!ELEMENT smallStep EMPTY>
<!ATTLIST smallStep minus CDATA #REQUIRED>
<!ATTLIST smallStep plus CDATA #REQUIRED>

<!ELEMENT percentComplete EMPTY>
<!ATTLIST percentComplete equals CDATA #REQUIRED>

<!-- crop the player (flash or silverlight) to obtain the "playable area" -->
<!ELEMENT crop EMPTY>
<!ATTLIST crop x CDATA #REQUIRED>
<!ATTLIST crop y CDATA #REQUIRED>
<!ATTLIST crop width CDATA #REQUIRED>
<!ATTLIST crop height CDATA #REQUIRED>

<!-- CONDITIONS -->

<!ELEMENT and (and|color|command|condition|frameLoaded|javascript|not|or|pref|title|url)+>
<!ELEMENT or (and|color|command|condition|frameLoaded|javascript|not|or|pref|title|url)+>
<!ELEMENT not (and|color|command|condition|frameLoaded|javascript|not|or|pref|title|url)>

<!ELEMENT color EMPTY>
<!ATTLIST color x CDATA "0">
<!ATTLIST color y CDATA "0">
<!ATTLIST color rgb CDATA #IMPLIED>
<!ATTLIST color op (dimmer-than|brighter-than) #IMPLIED>

<!ELEMENT command EMPTY>
<!ATTLIST command name CDATA #REQUIRED> <!-- pause|play|bigstep+|smallstep+|bigstep-|smallstep-|chapter+|chapter- -->

<!ELEMENT frameLoaded EMPTY>

<!ELEMENT javascript EMPTY>
<!ATTLIST javascript script CDATA #REQUIRED>
<!ATTLIST javascript matches CDATA #REQUIRED>

<!ELEMENT pref EMPTY>
<!ATTLIST pref name CDATA #REQUIRED>
<!ATTLIST pref exists (true|false) "false">

<!ELEMENT title EMPTY>
<!ATTLIST title matches CDATA #REQUIRED>

<!ELEMENT url EMPTY>
<!ATTLIST url matches CDATA #REQUIRED>

<!-- ACTIONS -->

<!ELEMENT click EMPTY>
<!ATTLIST click x CDATA #REQUIRED>
<!ATTLIST click y CDATA #REQUIRED>
<!ATTLIST click skipMouseUp (true|false) "false">

<!ELEMENT goto EMPTY>
<!ATTLIST goto state CDATA #REQUIRED>
<!ATTLIST goto param CDATA #IMPLIED>

<!ELEMENT lockPlugin EMPTY>

<!ELEMENT move EMPTY>
<!ATTLIST move x CDATA #REQUIRED>
<!ATTLIST move y CDATA #REQUIRED>

<!ELEMENT pause EMPTY>
<!ATTLIST pause time CDATA "0">

<!ELEMENT run EMPTY>
<!ATTLIST run script CDATA #REQUIRED>

<!ELEMENT type EMPTY>
<!ATTLIST type text CDATA #IMPLIED>
<!ATTLIST type key CDATA #IMPLIED>


<!ELEMENT visit EMPTY>
<!ATTLIST visit url CDATA #REQUIRED>

<!-- MISC -->

<!ELEMENT pre EMPTY>
<!ATTLIST pre m CDATA #REQUIRED>

<!ELEMENT setCookie EMPTY>
<!ATTLIST setCookie domain CDATA #IMPLIED>
<!ATTLIST setCookie path CDATA #IMPLIED>
<!ATTLIST setCookie name CDATA #IMPLIED>
<!ATTLIST setCookie secure CDATA #IMPLIED>
<!ATTLIST setCookie value CDATA #IMPLIED>

9.4.3. Keyboard Keycode Lookup

You can find the key code for use with the <type key="??"/> tag.

Use the Dec column from http://asciitable.com