<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

        <head>
                <meta http-equiv="content-type" 
content="text/html;charset=iso-8859-1">
                <meta name="generator" content="Adobe GoLive">
                <title>Untitled Page</title>
        </head>

        <body bgcolor="#ffffff">
                <h1>Time Ranges</h1>
                <h2>Discussion</h2>
                <p>In the current HTML5 draft cue ranges are 
available using a DOM API.</p>
                <p>This way of doing ranges is less than ideal. </p>
                <p>First of all, it is hard to use. The ranges must 
be added by script, can't be supplied with the media, and the 
callbacks are awkward to handle. The only way to identify the range a 
received callback applies to is by creating not one but two separate 
functions for each range: one for enter, one for exit. While creating 
functions on-demand is easy in JavaScript it does fall under advanced 
techniques that most authors will be unfamiliar with. This 
kind of feature is also not available in all languages that might 
provide access to the DOM API.</p>
                <p>Secondly this mechanism is not very powerful. You 
can't do anything else with the ranges besides receiving callbacks 
and removing them. You can't modify them. They are not visible 
to scripts or CSS. You can't link to them. You can't link out from 
them. </p>
                <p>Thirdly, a script is somewhat strange place to 
define the ranges. A set of ranges usually relates closely to some 
particular piece of media content. The same set of ranges rarely 
makes much sense in the context of some other content. It seems that 
ranges should be defined or supplied along with the media content.</p>
                <p>Fourth, this kind of callback API is pretty 
strange creature in the HTML specification. The only other callback 
APIs are things like setTimeout() and the new SQL API which don't 
have associated elements. Events are the callback mechanism for 
everything else.</p>
                <p>In SMIL the equivalent concept is the <area> 
element which is used like this: </p>
                <p><video 
src="http://www.example.org/CoolStuff"><br>
 
            
<area id="area1" begin="0s" 
end="5s"/><br>            
<area id="area2" begin="5s" 
end="10s"/><br>
                        </video></p>
                <p>This kind of approach has several advantages. </p>
                <ul>
                        <li type="disc">Ranges are defined as part of 
the document, in the context of a particular media stream.
                        <li type="disc">This uses events, a more 
flexible and more appropriate callback mechanism.<li type="disc">The 
callbacks have a JavaScript object associated with them, namely a DOM 
element, which carries information about the range.
                </ul>
                <p>The main disadvantage is the relative difficulty 
of creating ranges from JavaScript since it requires creating 
elements and giving them attributes. Some sort of shortcut interface 
could be provided, of course, perhaps similar to the existing API.</p>
                <p>The SMIL definition is perhaps a little broad and 
also the name is not ideal, if the element is primarily used for 
generating events vs. linking.</p>
                <p>We would like to suggest a <timerange> 
element that can be used as a child of the <video> and 
<audio> elements. </p>
                <h2>The timerange element</h2>
                <p><a href="#media7" title="media element">Media 
elements</a> may have <dfn id="cue-ranges0" title="cue 
range">timeranges as child elements</dfn>. A timerange represents an 
interval for which events will fire when the current playback time 
enters or leaves the interval.</p><p><strong>Contexts</strong> in 
which this element may be used:</p>
                <blockquote>
                        <p>As a child of a media element, after 
all source elements, and before any other content.</p>
                </blockquote>
                <p><strong>Content model</strong>:</p>
                <blockquote>
                        <p>Empty.</p>
                </blockquote>
                <p>Element-specific <strong>attributes</strong>:</p>
                <ul>
                        <blockquote>
                                <li type="disc">start
                                <li type="disc">end
                                <li type="disc">pauseonexit

                                <li type="disc">ontimeenter
                                <li type="disc">ontimeexit
                        </blockquote>
                </ul>
                <p><strong>DOM interface</strong>:</p>
                <blockquote>
                        <p>interface HTMLTimetimeElement : 
HTMLElement {<br>  
         attribute float 
start; <br>           attribute 
float 
end;<br>           attribute 
boolean pauseOnExit;<br>
 
           readonly attribute 
boolean active;<br>
                                };</p>
                </blockquote>
                <p>The start and end attributes of each timerange are 
'clipped' to the effective start and effective end of the media 
resource.  If the value of the end attribute is less than the value 
of the start attribute, it is automatically set to be equal to the 
start attribute. </p>
                <p>If start is not supplied, its default value is 
negative infinity, which means it gets assigned the effective start 
of the media resource.</p>
                <p>If end is not supplied, its default value is 
positive infinity, which means it gets assigned the effective end of 
the media resource.</p>
                <p>The timerange elements may be in any order (they 
might not be sorted) and may overlap.</p>
                <p>The "active" attribute of a time range 
is true when the currentTime of associated media element is greater 
to or equal to start and less than end. Otherwise it is false. Before 
any events fire, the active value of all timeranges is false, and it 
is also false when the current placyback position is at the effective 
end of the media resource.</p>
                <p>The ontimeenter and ontimeexit attributes are a 
convenient way to supply a handler for the corresponding events.</p>
                <h2>Behavior</h2>
                <p>When the active attribute of a timerange changes 
value from false to true a simple event "timeEnter" is 
fired. When the active attribute changes value from true to false a 
simple event "timeExit" is fired.  (These two names are 
deliberately similar to the spatial mouse events, but there is no 
timeMoved as it would fire continuously).</p>
                <p>If the same time value represents the end of one 
timerange and the start of another, then the timeExit event will fire 
before the timeEnter event. The "active" attribute of all 
ranges is set <em>before</em> all events are dispatched, for any time 
instant (so interrogating the DOM tree reveals the state that 
corresponds to the current playback position).</p>
                <p>When the <a href="#current0">current playback 
position</a> of a <a href="#media7">media element</a> changes (e.g. 
due to playback or
    seeking), the user agent must run the following steps. If the <a 
href="#current0">current playback position</a> changes while the 
steps are running, then the user agent must wait for the steps to 
complete, and then must immediately rerun the steps. These steps must 
also be run when a timerange element is added as a child of the media 
element, after all scripts have finished executing.  If a timerange 
is removed as a child of the media element while it is active, the 
timerange is set inactive, its timeExit event is fired, and then it 
is removed.</p>
                <p>(These steps are thus run as often as possible or 
needed — if one iteration takes a long time, this can cause 
certain ranges to be skipped over as the user agent rushes ahead to 
"catch up". Effectively time is "sampled" as 
often as both possible and necessary. This means that events for 
timeranges in which start equals end might never fire, but such 
timeranges are legal and user agents should attempt to fire their 
events.)</p>
                <ol>
                        <li>Let <var title="">current ranges</var> be 
an unordered list of <a href="#cue-ranges0" title="cue 
range">timeranges</a>, initialised to contain all the <a 
href="#cue-ranges0" title="cue range">timeranges</a> of the <a 
href="#media7">media element</a> whose start times are less than or 
equal to the <a href="#current0">current playback position</a> and 
whose end times are greater than the <a href="#current0">current 
playback position</a>.
                        <li type="1">Let <var title="">other 
ranges</var> be an unordered list of <a href="#cue-ranges0" 
title="cue range">timeranges</a>, initialised to contain all the <a 
href="#cue-ranges0" title="cue range">timeranges</a> of the <a 
href="#media7">media element</a> that are not present in <var 
title="">current ranges</var>.
                        <li type="1">Divide the ranges into four sets:
                                <ol>
                                        <li type="1">the <em>passive 
set</em>: <var title="">other ranges</var> which have their 
"active" boolean set to "false" (inactive).<li 
type="1">the <em>active set</em>: <var title="">current ranges</var> 
which have their "active" boolean set to "true" 
(active).<li type="1">the <em>entry set</em>: <var title="">current 
ranges</var> which have their "active" boolean set to 
"false" (inactive).<li type="1">the <em>exit set</em>: <var 
title="">other ranges</var> which have their "active" 
boolean set to "true" (active).</ol>

                        <li type="1">Set the "active" 
boolean of all the <a href="#cue-ranges0" title="cue 
range">timeranges</a> in the <var title="">entry set</var> to 
"true" (active), and the "active" boolean of all 
the <a href="#cue-ranges0" title="cue range">timeranges</a> in the 
<var title="">exit set</var> to "false" (inactive).

                        <li type="1">If the <em>entry set</em> and 
<em>exit set</em> are both empty, then abort these steps.
                        <li type="1">If the time was reached through 
the usual monotonic increase of the current playback position during 
normal playback, the user agent must then <a href="#firing2">fire a 
simple event</a> called <code title=event-timeupdate><a 
href="#timeupdate">timeupdate</a></code> at the media element. (In 
the other cases, such as explicit seeks, relevant events get fired as 
part of the overall process of changing the current playback 
position.)
                        <li type="1">If the time was reached through 
the usual monotonic increase of the current playback position during 
normal playback, and there are <a href="#cue-ranges0" title="cue 
range">timeranges</a> in the <em>exit set</em> that have their 
"pauseonexit" boolean set to "true", then 
immediately act as if the element's <code title="dom-media-pause"><a 
href="#pause0">pause()</a></code> method had been invoked. (In the 
other cases, such as explicit seeks, playback is not paused by 
exiting a timerange, even if that timerange has its 
"pauseonexit" boolean set to "true".)
                        <li type="1">Fire all the 
"timeExit" events for all of the <a href="#cue-ranges0" 
title="cue range">timeranges</a> in the <em>exit set</em>, in any 
order.
                        <li type="1">Fire all the 
"timeEnter" events for all of the <a href="#cue-ranges0" 
title="cue range">timeranges</a> in the <em>entry set</em>, in any 
order.
                </ol>
                <p>(Note that immediately before playback starts, and 
when the current playback position reaches the end of the media, 
there are no active timeranges.)</p>
                <p><strong>Constructor</strong>:</p>
                <blockquote>
                        <p>TimeRange(in float start, in float end); <br>
                                TimeRange(in float start, in float 
end, in boolean pauseOnExit); </p>
                </blockquote>
                <h2>Example</h2>
                <p><video 
src="http://www.example.org/CoolStuff"><br>

 
                    
<timerange id=r1 
end=10s></timerange><br>            
<timerange id=r2 
end=20s></timerange><br>            
<timerange id=r3 start=30s ></timerange><br>
                        </video></p>
                <p>video.addEventListener("timeEnter", 
function (event) {<br>
 
                    
switch (event.target.id) {<br>
 
                    
case r1: <br>
 
                    
            // 
do stuff<br>
 
                    
case r2: <br>
 
                    
            // 
do more stuff<br>
 
                    
}<br>
                        }, true);</p>
                <h1>Notes and Future Work</h1>
                <p>Note that there is an existing concept called 
timeranges in the HTML5 specification; a new name needs to be found 
for one or the other. </p>
                <p>The event listeners should probably be added to 
HTMLElement where other listener attributes are. (You should be able 
to capture events everywhere, not just on target.)</p>
                <p>It's possible that the identifiers of the 
time-ranges could be used as 'anchor points' within the media, so 
that activating them as a URL would cause the user agent to seek to 
the beginning of that range. This is related to the <a 
href="http://www.w3.org/2008/01/media-fragments-wg.html">Media 
Fragments</a> working group.</p>
                <p>Similarly, it's possible that href URLs could be 
added to timeranges, such that if the user clicked on the media 
during the range, the href URL would be dispatched. (This could also 
be integrated with a usemap). </p>
                <p>Both of these have scoping and other implications 
and we think can be left to further study.</p>
                <p>The existing API for adding a timerange to the DOM 
could be retained as a convenient shortcut, but we don't think it is 
needed.</p>
                <p>There could be a timemoved event fired at 
timeranges that want it, but there would need to be some sort of 
movement granularity attribute, or other control, or else it would 
effectively have to be run at every change of value of the current 
placyback position, up to and including saturating the CPU.</p>
        </body>

</html>