Freigeben über


Dissecting "Chapters"

Hello World is a very basic application.  But, now let's take a look at one of the samples that has a little bit more complexity to it.  In the Jumpstart samples folder you'll find the Chapters sample.  Open up C:\Program Files\HD DVD Interactivity Jumpstart\Samples\Chapters.

We're starting out at a higher level here than Hello World.  You'll notice that this project has an ADV_OBJ folder like Hello World, but it also has a HVDVD_TS folder.  The HVDVD_TS folder holds the video assets for your project.  This particular HVDVD_TS folder contains two Windows Media files - fbi_warning.wmv and movie.wmv.  The Jumpstart kit does not play the real content that you will use on your disc; it will only play Windows Media files.  You may change the extension on these .wmv files to .MAP to match the names of your real assets, but for the simulator, the files themselves must be Windows media.

Now go to the ADV_OBJ folder and open the playlist VPLST000.XPL file in your editor.  Like the Hello World application, there is a title that contains the application (so it is a "title application" rather than a "playlist application").  Unlike the Hello World application, the titles in this playlist each have a PrimaryAudioVideoClip which references one of the videos in the HVDVD_TS folder.  Also, the second title has a ChapterList which marks the times at which chapter markers are located.

The manifest for this application is called main.xmf.  If you open it up, you will see resources and markup listed like Hello World.  But in addition, there is a Script tag with main.js as the src.  Note that main.js is referenced by this Script tag as well as in a Resource tag - both are required.

This particular application has only one script file, but you can have more than one Script tag.  Keep in mind, though, that the order you reference them may matter just as it would if you were writing JavaScript for the web. 

Open up main.js script file in your editor.  A couple of things to note about this file... It is saved with UTF-16 Big Endian encoding - this is a requirement according to the HD DVD specification.  Also, there is an extra white space at the bottom.  When you have multiple script files, they are concatenated in to one large file.  There's an explanation about why you will want to do this here.

HD DVD uses the compact profile of ECMAscript (which restricts use of "with" and "eval" and does not implement optional menthods like substr).  If you've done development with JavaScript before, some of this file probably looks fairly familiar.  The parts that might not are specific HD DVD APIs (found in  Annex Z of the HD DVD spec).

What's going on in main.js

This script primarily exists to receive events from the markup file and execute some action.  Event listeners are created for ButtonChapter1Event (line 35), ButtonChapter2Event (line 36), and ButtonChaper3Event (line 37).  These are custom events that are dispatched by the markup and handled in the script. 

There are three corresponding functions which handle the events - ButtonChapter1EventHandler (line 14), ButtonChapter2EventHandler (line 20), and ButtonChapter3EventHandler (line 26).  The event handler functions use the Playlist object to jump to the beginning ("00:00:00:00") of the specified chapter within the titled with the id "Main". 

How does the markup pass the event to the script?

Now, I said that the script received these custom events from the markup, but how do you dispatch an event from the markup? 

Open up main.xmu in your editor.  Notice that unlike Hello World, this application has elements in the timing block.   This timing block uses the page clock (line 26).  A timing block can use either a page clock or a title clock.  Use a title clock when cues should occur at specific timecodes during the movie (like what you see during the Warner Bros. In-Movie Experience or Universal's U-Control).  Use a page clock for cues that are time independent have times that are relative to other cues (like menus).  Your markup may use both timing blocks if needed.

The first tag in our timing is defs (line 27).  This element is used to define a set of reusable animations or groups.  For instance, one of the defs with the id of "ButtonFocused" (line 28) is used to set the backgroundFrame of an element to 1 and the opacity to 1.0.  This definition can be referenced later by calling use="ButtonFocused" to apply this style change to a selected div.

You may also define groups under defs using the g tag.  Notice "gButtonChapter1" (line 35).  When this def is used, the backgroundFrame of the selected element is set to 2 and the event "ButtonChapter1Event" is dispatched.

The "ButtonChapter1Event" event in this example does not contain parameters.  However, this event could have be changed to:

<event name="ButtonChapterEvent">
    <param name="Chapter" value="1"/>
</event>

And the script would then listen for this event (noticed, I changed the name) and access the "Chapter" parameter passed by the event.

application.addEventListener("ButtonChapterEvent",ButtonChapterEventHandler,true);

function ButtonChapterEventHandler(objEvent)
{
    var chapter = parseInt(objEvent.Chapter)-1;
    // jump to the begining of the first chapter of the "Main" title 
    Player.playlist.titles["Main"].chapters[chapter].jump("00:00:00:00",false);
}

How does the user trigger the event?

Okay, we're seen how the script listens for the event and how it handles the event.  We've seen how the markup uses an event element to dispatch the event.  Now, how does the user action trigger that event? 

Remember, "ButtonChapter1Event" was contained within the "gButtonChapter1" group.  Looking at our timing block, we see that it is used in the cue on line 49.  This cue begins (is triggered) when the state of "ButtonChapter1" is actioned (the user had focus on the button and pressed the "Enter" key).  And, if you go down to the body section of the markup, you will see that "ButtonChapter1" is a button declared on line 89 which can indeed receive focus and be actioned by the user.

In Summary

The markup body contains a button called "ButtonChapter1". 

When the user focuses this button and hits enter the button's actioned state changes to true, a cue in the timing element begins.

This cue uses the group definition "gButtonChapter" which sets the background frame of "ButtonChapter1" to 2 and dispatches the event "ButtonChapter1Event". 

The script main.js has an event listener for the "ButtonChapter1Event". 

Finally, the function "ButtonChapter1EventHandler" handles the event by jumping to the first chapter in the title "Main"