Detailed Instructions
For this example, we’re creating a movie that presents the viewer with a choice: Red Pill or Blue Pill. Depending on the viewer’s choice, the movie shows one of two alternate endings.
To achieve this, we have split the movie into three video segments: the Introduction, the “Red Pill” Ending, and the “Blue Pill” Ending.
We also have two images that are displayed during the choice prompts: the Choice 1 Wait Screen: 
…and the Closing Wait Screen: 
While these could also be implemented as video segments, since there is no motion in them, using images saves on file size and thus download overhead.
Put together, the playback sequence looks like this: Intro → Choice 1 Wait Screen → ( “Red Pill” Ending OR “Blue Pill” Ending ) → Closing Wait Screen.
With RedBlue, you don’t have to write the logic to achieve this playback sequence yourself. You simply use declarative HVML markup to specify the available choices and which files to play for each choice. The player code handles the rest.
Setup
- Import the RedBlue video player Custom Element. (This requires ES6 support to work directly in the browser; otherwise the source code can be transpiled to ES5.)
<script type="module">
import RedBlueVideo from './modules/redblue-video-compat.js';
customElements.define( RedBlueVideo.is, RedBlueVideo );
</script>
- Include an HVML code block as a child of
<redblue-video>
. HVML can be represented as either XML or JSON-LD. When using the XML serialization, set the boolean hidden
attribute to true to prevent the browser from rendering the metadata.
<redblue-video>
<hvml xmlns="https://hypervideo.tech/hvml#" hidden="hidden"></hvml>
</redblue-video>
- In the HVML, specify a single
video
element. (Not to be confused with HTML’s video
element—though unless your page is served as XHTML, technically the browser will interpret it as such.) This is the container for all of your video’s metadata.
<redblue-video>
<hvml xmlns="https://hypervideo.tech/hvml#" hidden="hidden">
<video></video>
</hvml>
</redblue-video>
- Under
video
, set basic metadata:
title
published
, the date of first public release
runtime
, usually an integer denoting minutes or an ISO 8601 duration, but in this case the string “variable” indicates a branching narrative whose runtime depends on choices made
description
<redblue-video>
<hvml xmlns="https://hypervideo.tech/hvml#" hidden="hidden"></hvml>
<video>
<title>RedBlue Test</title>
<published>2014</published>
<runtime>variable</runtime>
<description>Branching narratives demo</description>
</video>
</hvml>
</redblue-video>
Nonlinear Playlists
In HVML, branching narratives are achieved by what is termed a nonlinear playlist. Nonlinear playlists are like regular playlists in that they specify a list of media files to be played back sequentially. But in nonlinear playlists, choice prompts can be queued in addition to media files. When the playhead encounters a choice prompt, the viewer is presented with one or more options that, when selected, redirect the playhead to different parts of the playlist. Each choice prompt can be assigned a wait screen, a background video or image to display while waiting for the viewer’s input. In our example, the Red Pill/Blue Pill choice prompt features a closeup of Morpheus’s hands as its wait screen.
When creating nonlinear playlists, there are three HVML elements to be familiar with.
2. choicePrompt
A choicePrompt
element instructs the RedBlue Player to present the viewer with one or more options to choose from. Under it, you can provide:
- A
name
element, instructing the RedBlue Player to render heading text on top of the wait screen;
- A
media
element, specifying a video or image file to use as the wait screen;
- One or more
choice
elements, specifying the options to present to the user.
<choicePrompt xml:id="red-pill-or-blue-pill">
<name>What will it be, Neo?</name>
<media
xlink:href="#xpointer(//file[@label='choice-1-wait-screen'])"
></media>
<choice>
</choice>
<choice>
</choice>
</choicePrompt>
3. choice
A choice
element instructs the RedBlue Player to render one of a set of options, usually in the form of a link. choice
s can be overlaid onto specific regions of the player, making them hotspots. When the viewer selects a choice, an action is performed, typically moving the playhead to another point in the playlist.
Under choice
, you can provide:
- A
name
element, setting the link text. Link text may be invisble if the choice
represents a hotspot;
- A
goto
element, instructing the RedBlue Player to follow the URL specified in its xlink:href
attribute. If the URL resolves to another playlist item, the playhead will be moved there. A goto
’s xlink:actuate
attribute being set to “onRequest” specifies that the viewer needs to request the URL manually (here, by clicking on the link) before the player will follow the URL.
<choice xml:id="red">
<name>Red Pill</name>
<goto
xlink:actuate="onRequest"
xlink:href="#wakes-up-to-reality"
></goto>
</choice>
Putting It All Together
With all of our file
elements set up, let’s assemble the nonlinear playlist to put them to use.
Intro
- Under
presentation
, add a playlist
element.
- Set its
type
attribute to “nonlinear”. This attribute activates RedBlue’s interactive playback mode.
<redblue-video>
<hvml xmlns="https://hypervideo.tech/hvml#" hidden="hidden">
<video>
<title>RedBlue Test</title>
<published>2014</published>
<runtime>variable</runtime>
<description>Branching narratives demo</description>
<presentation>
<playlist type="nonlinear"></playlist>
</presentation>
</video>
</hvml>
</redblue-video>
- Under
playlist
, add a media
element.
- Set its
xml:id
attribute to a globally-unique ID so it can be independently referenced.
- Set its
xlink:href
attribute to the XPointer expression #xpointer(//file[@label='intro'])
. This selects every file
with a label
attribute equal to “intro”.
<redblue-video>
<hvml xmlns="https://hypervideo.tech/hvml#" hidden="hidden">
<video>
<title>RedBlue Test</title>
<published>2014</published>
<runtime>variable</runtime>
<description>Branching narratives demo</description>
<presentation>
<playlist type="nonlinear">
<media
xml:id="intro"
xlink:href="#xpointer(//file[@label='intro'])"
></media>
</playlist>
</presentation>
</video>
</hvml>
</redblue-video>
- Under
media
, add a goto
element. This sets up a playhead redirect.
- Set its
on
attribute to durationEnd
. This tells the RedBlue Player not to activate the redirect until the parent media
element is done playing.
- Set its
xlink:href
to the ID selector #red-pill-or-blue-pill
. This will point to a choicePrompt
element shortly.
<redblue-video>
<hvml xmlns="https://hypervideo.tech/hvml#" hidden="hidden">
<video>
<title>RedBlue Test</title>
<published>2014</published>
<runtime>variable</runtime>
<description>Branching narratives demo</description>
<presentation>
<playlist type="nonlinear">
<media
xml:id="intro"
xlink:href="#xpointer(//file[@label='intro'])"
>
<goto
on="durationEnd"
xlink:href="#red-pill-or-blue-pill"
></goto>
</media>
</playlist>
</presentation>
</video>
</hvml>
</redblue-video>