/
index.html
1577 lines (1300 loc) · 118 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<title>Timing Object</title>
<meta charset="utf-8">
<script src="http://www.w3.org/Tools/respec/respec-w3c-common"
async class="remove"></script>
<script class="remove">
var respecConfig = {
specStatus: "ED",
edDraftURI: "http://webtiming.github.io/timingobject",
shortName: "timing-object",
editors: [
{
name: "François Daoust",
company: "W3C",
companyURL: "http://www.w3.org",
mailto: "fd@w3.org"
},
{
name: "Ingar M. Arntzen",
company: "Motion Corporation",
companyURL: "http://motioncorporation.com/",
mailto: "ingar.arntzen@motioncorporation.com"
}
],
authors: [
{
name: "Njål T. Borch",
company: "Motion Corporation",
companyURL: "http://motioncorporation.com/",
mailto: "njaal.borch@motioncorporation.com"
}
],
wg: "Multi-Device Timing Community Group",
wgURI: "http://www.w3.org/community/webtiming/",
wgPublicList: "public-webtiming",
localBiblio: {
"LINEARCOMPOSITION": {
title: "Multi-device Linear Composition on the Web: Enabling Multi-device Linear Media with HTMLTimingObject and Shared Motion",
href: "https://sites.google.com/site/mediasynchronization/Paper4_Arntzen_webComposition_CR.pdf?attredirects=0&d=1",
authors: [
"Ingar M. Arntzen",
"Njål T. Borch",
"François Daoust",
"Dominique Hazaël-Massieux"
]
},
"MSV": {
title: "The Media State Vector: A unifying concept for multi-device media navigation",
href: "http://dl.acm.org/citation.cfm?doid=2457413.2457427",
authors: [
"Ingar M. Arntzen",
"Njål T. Borch",
"Christopher P. Needham"
]
},
"DVB-CSS": {
title: "ETSI TS 103 256-2 V1.1.1 Digital Video Broadcasting (DVB); Companion Screens and Streams; Part 2: Content Identification and Media Synchronization",
href: "http://www.etsi.org/modules/mod_StandardSearch/pdf.png"
},
"SHAREDMOTION": {
title: "Shared Motion",
href: "http://motioncorporation.com"
},
"MEDIASYNC":{
title: "MediaSync",
href: "https://github.com/webtiming/mediasync"
},
"SEQUENCER" : {
title: "Open-source sequencer library",
href: "https://github.com/webtiming/sequencer"
}
}
};
</script>
<style type="text/css">
table { border-collapse: collapse; border-style: hidden hidden none hidden; }
table thead, table tbody { border-bottom: solid; }
table td, table th { border-left: solid; border-right: solid; border-bottom: solid thin; vertical-align: top; padding: 0.2em; }
</style>
</head>
<body>
<!-- ABSTRACT -->
<section id="abstract">
<p>
This specification defines the timing object. The timing object is a local object that may be used by Web clients to ensure precisely timed operation as well as flexible timing control. If multiple timing-sensitive components take direction from the same timing object, their behaviour will be precisely aligned in time (synchronized). Crucially, this is also the case in distributed settings. A central motivation for the timing object is that it may be connected to an online timing resource. This way, the local timing object is a gateway to precisely timed operations, both in single-device and multi-device scenarios.
</p>
<p class="note">
This timing object is not to be confused with concepts proposed by
<a href="https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html">Navigation Timing</a>, an initiative targeting precise measurement of time consumption in Web browsers.
</p>
</section>
<!-- STATUS OF DOCUMENT -->
<section id="sotd">
<p>
The specification is intended for discussion within the Multi-Device Timing Community Group. Its content does not yet represent the consensus of the Community Group.
</p>
<p class="warning">
This specification is incomplete. Some procedures are either missing or described as <em>similar to procedures defined in [[!HTML5]]</em>. The main goal of this draft is to propose a technical solution, show how it could be integrated in [[!HTML5]] and gather feedback from interested parties before dwelving into details.
</p>
</section>
<!-- INTRODUCTION -->
<section class="informative">
<h2>Introduction</h2>
<p>
Timing mechanisms allow operations to be executed at the correct time. The Web already has several mechanisms supporting timed operations, including <code>setTimeout</code>, <code>setInterval</code>, as well as media frameworks and animation frameworks for timed media presentation. Unfortunately, these mechanisms are limited in scope as they only apply to timed operations within a single web page. The <a href="https://www.w3.org/community/webtiming/">W3C Multi-device Timing Community Group</a> has been formed with the goal of extending the Web with native support for precisely timed operation across Web pages hosted by different devices, as well as providing a unifying timing model to which all frameworks for timed operation may integrate. The timing object is the central concept in this initiative.
</p>
<p>
Synchronized playback of multi-device linear media is an important use-case for multi-device timing. However, multi-device timing has wide utility for a variety of timing related challenges, including distributed media control and remote control, distributed synchronization, distributed time-shifting, distributed time-ordering and distributed capture/recording (time-stamping). This way, multi-device timing has applicability in many application domains, including TV and radio (broadcast and IP-based), secondary device applications, online education, VoD services, social and collaborative media, data visualization, music etc.
</p>
<p>
For a more detailed list of use cases that this specification enables, see <a href="#use-cases-and-requirements"></a>.
</p>
<section>
<h3>Linear composition</h3>
<p>
<dfn lt="linear composition|linear composability">Linear composition</dfn> or <dfn>temporal composition</dfn> is simply the idea that complex linear media can be built from simpler, independent linear components. Web support for linear composition would imply that classical benefits of composition, i.e. flexibility, reusability, extensibility and mashup-ability, apply to the construction of Web-based linear media. For example, in the single-device scenario, imagine a linear presentation made from HTML5 video, some timed meta-information, a SMIL component, a Web Animation, a map with timed georeferenced data, and a timed Twitter widget. Or, in the multi-device scenario, imagine the same components distributed or duplicated across multiple devices in a room or within a social group. In both cases linear composition requires temporal interoperability among heterogeneous linear components, available through precisely coordinated, timed playback.
</p>
<p>
Unfortunately, Web support for linear composition is not optimal. Each media framework tend to define its own custom timing control mechanisms, making it difficult to achieve <a>linear composition</a> in practice. The central purpose of the timing object is thus to simplify interoperability by providing a common basis for timed operation and control in linear media.
</p>
<p>
For a more detailed introduction to linear composition on the Web, see [[LINEARCOMPOSITION]].
</p>
</section>
<section>
<h3>Design goals</h3>
<p>
The design of the timing object has two main goals:
</p>
<ol>
<li>
<b>provide a unifying API for timed operation and temporal control</b> that timed components can integrate with. This would include timing sensitive Web applications in general, as well as existing frameworks for timed media — such as <a>media elements</a> in [[HTML5]], Web Animations [[WEB-ANIMATIONS-1]], Web Audio API [[WEBAUDIO]] and SMIL Timing [[SMIL3]]. The API must support highly precise timing and be expressive enough to support control primitives appropriate for a wide range of media types and applications.
</li>
<li>
<b>encapsulate complexity of distributed time synchronization</b>, thereby allowing integrating frameworks to be included in precisely timed multi-device operation. In particular, by providing the same API for local and online timing resources, timed components may be used in single-device and multi-device scenarios, without modification.
</li>
</ol>
<p>
<a href="#fig-timingobject-overview">Fig. 1</a> below illustrates these functions, including an online service to provide multi-device timing. In this example, a timing object is instantiated on each of the three devices, and each instance is connected to a single, shared online timing resource. On each device, the timing object acts as the director for independent, timing-sensitive UI components. This way, a video will aim to present video frames in accordance with the timing resource. Similarly, a timing-sensitive Twitter widget might replay timestamped Tweets. If the timing object pauses, all the connected components are notified and react accordingly. Note that the different UI components may go about their business in complete isolation. There is no need for components to communicate, except indirectly through the timing object. This loose coupling is the key to <a>linear composability</a>.
</p>
<figure id="fig-timingobject-overview">
<img src="overview.png" width="400" alt="The image illustrates the concept of an online timing resource how it used to synchronize HTTPTimingObjects across three different Web clients." />
<figcaption>Timing objects on three devices connected to the same online timing resource</figcaption>
</figure>
<p>
Furthermore, when timing objects are connected to an online timing resource, they merely act as local representatives. For example, when requested to pause, the timing object will simply forward the request to the online timing resource. As the online object pauses, notifications will be multicast to all connected clients. The timing object will only update its internal state and notify connected UI components when it receives this notification. For online timing objects, clients can expect update latency of about one round trip time (RTT), whereas local timing resources should have no update latency. Apart from this, online and local timing resources should be hard to distinguish. Note also that the argument made for the independence of timing-sensitive components in the single-device scenario now applies to the multi-device scenario as well.
</p>
<p class="note">
This specification describes the integration of timing objects with HTML5 Media elements and text tracks. Integration with other frameworks for timed operation, such as Web Animation, SMIL, and WebAudio will be covered separately.
</p>
</section>
<section>
<h3>The timing object</h3>
<p>
The timing object is a very simple object, essentially an advanced stop watch (<a href="#fig-stopwatch">Fig. 2</a>). If started, its value changes predictably in time, until at some point later, it is paused, or perhaps reset. It may be queried for its value at any time. For example, it should take exactly 2.0 seconds for the value to advance from 3.0 to 5.0 when the velocity is 1.0. Such deterministic behavior is required for reliable distributed synchronization. In terms of implementation, the timing object is a fairly thin wrapping around a monotonic system clock (integration with online timing resources adds complexity). The precision of the timing object is limited by the underlying system clock.
</p>
<figure id="fig-stopwatch">
<img src="stopwatch_digital.jpg" width="160" alt="The timing object is essentially an advanced stop watch." />
<figcaption>The timing object is essentially an advanced stop watch.</figcaption>
</figure>
<p>
The timing object is more expressive than a traditional stop watch. It supports any velocity or acceleration, and may jump (instantaneously) to any position on the timeline (<a href="#fig-timeline">Fig. 3</a>). In fact, a timing object essentially implements <em>linear motion along a unidimensional axis</em>. State vectors [[MSV]], based on the classical equations of linear motion under constant acceleration, are used to represent that motion. At any point in time, position, velocity or acceleration may be requested to change. Querying the timing object reveals not only its current position but also its velocity and acceleration at that moment. The expressiveness of this model implies that a wide variety of control primitives can be supported. For example, discrete jumps on the timeline may be used to control a slide show, or velocity may correspond to <code>playbackRate</code> for the control of continuous media. Acceleration may be for instance be required by animation frameworks.
</p>
<figure id="fig-timeline">
<img src="timeline.png" width="400" alt="The timing object is essentially and advanced stop watch." />
<figcaption>The timing object visualized as a cursor moving along a time-axis.</figcaption>
</figure>
</section>
<section>
<h3>Programming with timing objects</h3>
<p>
Timing objects are resources used by a Web application, and the programmer may define as many as required. What purposes they serve in the application is up to the programmer. If the application needs a shared, multi-device clock, simply starting a timing object (and never stopping it) might be sufficient. If the clock value should represent milliseconds, set the velocity to 1000 (advances the timing object with 1000 milliseconds per second). If the timing object represents media offset, specify the playback position, the velocity, and perhaps a media duration. For videos where offset is measured in seconds or frames, set the velocity accordingly. Or, for musical applications it may be practical to let the timing object represent beats per second. Note also that the timing object may represent time-changes with any kind of floating-point variable. For example, if you have data that is organized according to, say height above sea level, you may want to animate how this data changes as you move vertically. In this case the timing object could represent meters or feet above sea level, and positive and negative velocities would allow you to move gradually both upwards and downwards.
</p>
<p>
In general, the timing object is particularly useful when you have a variable that needs to change predictably in time.
</p>
</section>
<section>
<h3>Connecting the timing object</h3>
<p>
The proposed timing model is one where timed components are <i>connected</i> to <a>timing objects</a>, thereby accepting the <a>timing object</a> as director of timed operation. In other words, the <a>timing object</a> is the master, and the timed component is the slave. However, the <i>connection</i> is not entirely one-way. Timed components may also enforce control over the <a>timing object</a> by issuing update requests. This allows interactive components to implement timing control on behalf of end users. For instance, a UI element implementing media controls may both be a slave of a <a>timing object</a> by slavishly visualizing media offset, while at the same time allow the end user to pause the presentation by clicking a the pause button. Crucially, control enforced on a <a>timing object</a> applies equally on all <i>connected</i> components.
</p>
<p>
Flexibility is another feature with this timing model. Since the <a>timing object</a> is an independent object, timed components and <a>timing objects</a> may be <i>connected</i> and <i>disconnected</i> dynamically. For example, in the context of live media presentation, flexible switching may be enabled between a <a>timing object</a> (representing the <i>public, live-head</i> of an experience), and a different <a>timing object</a> (representing <i>private, personal, time-shifted</i> experience). Another example would be switching to a different <a>timing object</a> in order to join a friend in a co-viewing session.
</p>
<p>
To support this timing model, a clear separation between <a>timing object</a> and consuming components is required. Specifically, a pattern emerges where timed components are given a reference to a <a>timing object</a> through a <i>timingsrc</i> property. On the other hand the <a>timing object</a> is kept usage agnostic and clean of references to consuming components.
</p>
<p>
Timed components that need to <i>connect</i> with the <a>timing object</a> broadly fall into two categories; components which already have an internal timing model, and components that do not. Within the first category we specifically have media players and existing media frameworks. For such components <i>connection</i> with the <a>timing object</a> mainly implies time-alignment of the internal timing model with the external <a>timing object</a>. In particular, this document discusses integration with <a>media elements</a>, see <a href="#media-elements-and-the-timing-object">media elements and the timing object</a>.
</p>
<p>
Components within the second category do not provide their own timing model, but may be useful for presenting timed data. UI elements such as map and canvas fall into this category. Custom components such as plotting libraries, media controls, subtitle viewers, Twitter widgets etc., may also need to <i>connect</i> with a <a>timing object</a> (in order to present data consistently in time). In fact, an entire Web page may be considered a timed component, where replacement of both data and presentational elements is directed by a <a>timing object</a>. All these timed components have a single challenge in common, the need to present or execute timed data at the correct time, i.e. time-aligned with the <a>timing object</a>. This document addresses this common need by <i>connecting</i> the <a>timing object</a> with a <a>text track</a>, see <a href="#timed-data-and-the-timing-object">timed data and the timing object</a>.
</p>
<p>
Finally, in order to support precisely timed operation in multi-device applications, the <a>timing object</a> must be <i>connected</i> with an <a>online timing resource</a>. One could imagine future standardization of a protocol between <a>timing object</a> and the online timing service. Currently though, the decision is rather to leave space open for innovation among timing providers. The <dfn>TimingProvider</dfn> interface is introduced (see <a href="#timing-provider-object"></a>). The idea is that third parties may provide different implementations of <a>timing provider objects</a> (JavaScript), to which <a>timing objects</a> may then connect. As a result, the <i>connection</i> to a <a>timing provider object</a> may be provided by the inclusion of a third party JavaScript library.
</p>
</section>
<section>
<h3>Media capture and playback</h3>
<p>
Two very common uses of the timing object include media capture and playback. For media playback, the timing object may play the role of director or controls. Multiple independent components, possibly on different devices, may be responsible for timed presentation of timed media. If all components take direction from a single timing object, playback is ensured to be timing-consistent.
</p>
<p>
For media capture, the timing object may represent a shared clock for timestamping various types of captured media in multi-device scenarios. As long as timestamps are sampled from a shared clock and included in the captured media, time-shifted playback is possible. In live capturing scenarios, the timing object should likely just run continuously like a clock, or perhaps be adjusted slightly from time to time to stay in sync with some real-world clock source, e.g. a trusted source for epoch time. On the other hand, media capture in a studio setting may be a much more of an iterative process, recording one track or sample at a time. In such scenarios, the timing object might have to be paused and rewound for each take. The timing object will then play the dual role of playback director for previously captured media, as well as production clock for current capture.
</p>
</section>
<section>
<h3>Reference point in capture and playback</h3>
<p>
The concept of reference point refers to the exact time-alignment of timing object and media in capture and playback. Disagreement about the details of this alignment may be a source of (small) synchronization errors. For this reason, a common definition of reference points for time alignment in capture and playback is helpful.
</p>
<p>
For media capture, media timestamps should reflect the point in time when external, physical signals are received by sensors. I.e., ideally when photons hit the lense or when sound waves hit the microphone. So, as timestamping activity is delayed relative to this ideal reference point, timestamps picked from the timing object must be adjusted (upstream delay subtracted). This implies that capturing components must know (or figure out) their upstream latency (if significant). If all components are able to do this correctly, variation in processing delay will not produce synchronization errors.
</p>
<p>
For media playback, media timestamps should reflect the point in time when timed media fragments take physical effect. I.e., ideally when pixels are modified on the screen, or when the loudspeaker modifies its vibration frequency. If playback commands are subject to non-negligible delay before they take effect, the playback component must schedule commands earlier. This implies that playback component must know (or figure out) their downstream delay. If all components are able to do this correctly, variation in processing delay will not produce synchronization errors.
</p>
<p class="note">
This definition of reference points is in accordance with definitions used in related standardization work, for instance see [[DVB-CSS]] / HbbTV2.0 CSS clause 5.7.2.
</p>
<p class="note">
Strictly speaking, the timing object is usage-agnostic and can not mandate a specific definition for reference point. However, as interoperability of timing-sensitive components (e.g. capture and playback) is a major motivation for the timing object, the above definitions for reference point are recommended.
</p>
</section>
<section>
<h3>Naming</h3>
<p>
With regards to the naming of the <a>timing object</a>, there were multiple options available, e.g. <i>Clock</i>, <i>WebClock</i>, <i>MediaClock</i> or <i>SharedClock</i>. For a descriptive name, we argue that <i>clock</i> (or variations thereof) might be a bit limiting. A <i>clock</i> (in particular a system clock) is mainly a read-only resource (from the perspective of the programmer). <i>Stop-watch</i> would better indicate the interactive nature of the <a>timing object</a>, however, this too would fail to indicate the role of the <a>timing object</a> as <i>controller</i> or <i>director</i> in media. From a purely descriptive point of view, deterministic <i>motion</i> is perhaps the most precise name, matching the implementation and also indicating that linear media is made from two basic constituents - media <i>content</i> and media <i>motion</i>. On the other hand, the term <i>motion</i> is (still) unfamiliar and does not indicate any specific uses. For these reasons it was decided to name the object after its main purpose which is correct timing and temporal control. Something like <i>TemporalControllerObject</i> or <i>TimingDirectorObject</i> would perhaps be most correct. However, as these terms are a bit clunky <i>TimingObject</i> was selected as an acceptable compromise.
</p>
</section>
</section>
<!-- CONFORMANCE -->
<section id="conformance">
<p>
Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and terminate these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc.) used in introducing the algorithm.
</p>
<p>
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant).
</p>
<p>
This specification defines conformance criteria for two classes of products:
</p>
<ul>
<li>A <dfn>user agent</dfn> that provides the Web runtime and implements all the interfaces defined in <a href="#timing-object"></a>, <a href="#state-vector"></a>, <a href="#media-elements-and-the-timing-object"></a> and <a href="#timed-data-and-the-timing-object"></a>.</li>
<li>A <dfn>timing resource provider</dfn> that provides necessary logic to associate a <a>timing object</a> with an online <a>timing resource</a>. A <a>timing resource provider</a> implements the <code><a>TimingProvider</a></code> interface defined in <a href="#timing-provider-object"></a>.</li>
</ul>
</section>
<!-- TERMINOLOGY -->
<section>
<h2>Terminology</h2>
<p>
The following terms, procedures and interfaces are defined in [[!HTML5]]:
</p>
<ul>
<li><dfn lt="event handler|event handlers"><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#event-handlers">event handler</a></dfn></li>
<li><dfn lt="event handler event type|event handler event types"><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#event-handler-event-type">event handler event type</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#queue-a-task">queue a task</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#fire-a-simple-event">fire a simple event</a></dfn></li>
<li><dfn lt="media element|media elements"><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#media-element">media element</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#media-timeline">media timeline</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#effective-playback-rate">effective playback rate</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#current-media-controller">current media controller</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#slaved-media-elements">slaved media elements</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#report-the-controller-state">report the controller state</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#seek">seek</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#media-data">media data</a></dfn></li>
<li><dfn lt="text tracks"><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track">text track</a></dfn></li>
<li><dfn lt="text track cue|text track cues"><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track-cue">text track cue</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track-kind">text track kind</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track-label">text track label</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track-language">text track language</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track-mode">text track mode</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track-hidden">text track hidden</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track-loaded">text track loaded</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track-readiness-state">text track readiness state</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#text-track-list-of-cue">text track list of cues</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#list-of-text-tracks">list of text tracks</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#list-of-newly-introduced-cues">list of newly introduced cues</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#current-playback-position">current playback position</a></dfn></li>
<li><dfn><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#time-marches-on">time marches on</a></dfn></li>
<li><dfn><code><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#htmlmediaelement">HTMLMediaElement</a></code></dfn></li>
<li><dfn><code><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#mediacontroller">MediaController</a></code></dfn></li>
<li><dfn><code><a href="http://www.w3.org/html/wg/drafts/html/master/webappapis.html#texttrack">TextTrack</a></code></dfn></li>
</ul>
<p>
The following interfaces are defined in [[!DOM]]:
</p>
<ul>
<li><dfn><code><a href="http://www.w3.org/TR/dom/#event">Event</a></code></dfn></li>
<li><dfn><code><a href="http://www.w3.org/TR/dom/#interface-eventtarget">EventTarget</a></code></dfn></li>
</ul>
<p>
The <code><a href="http://dev.w3.org/html5/spec/webappapis.html#eventhandler">EventHandler</a></code> interface represents a callback used for <a>event handlers</a> as defined in [[!HTML5]].
</p>
<p>
The <dfn>performance clock</dfn> refers to the precise, high-resolution, and monotonic clock defined in [[!HR-TIME]] (and exposed through the <code>Performance.now()</code> method).</li>
</p>
<p>
A <dfn>timing resource</dfn> is an object. This object essentially implements the abstraction of a <i>linear motion in real time</i>. For example, imagine a <i>point</i> moving along an <i>axis</i>. At a specific moment in time, this <i>point</i> has a specific <i>position</i> on the <i>axis</i>, a specific <i>velocity</i> and a specific <i>acceleration</i>. These three properties (all floating point values) define the state of the <a>timing resource</a> at that moment in time.
</p>
<p>
A <a>timing resource</a> may either be an <dfn>internal timing resource</dfn>, an object under the control of a <a>user agent</a>, or an <dfn>external timing resource</dfn>, an object under the control of a <a>timing resource provider</a>. Both types exist locally in the user agent, but the <a>external timing resource</a> may be a proxy object for an <dfn lt="online timing resources">online timing resource</dfn>, i.e. an object hosted remotely by an online service.
</p>
<p class="note">
A <a>user agent</a> may typically offer native implementations of <a>timing objects</a>, especially when the protocol needed is not available to Web applications. For instance, the clock synchronization mechanism defined in DVB for companion screens and streams [[DVB CSS]] uses a UDP-based protocol. A <a>user agent</a> could perhaps expose a <code>DVBCSSTimingObject</code> interface to allow Web applications to connect to a companion screen that supports this protocol.
</p>
<p>
</p>
<p>
This document provides interface definitions using the [[!WEBIDL]] standard.
</p>
</section>
<!-- EXAMPLES -->
<section class="informative">
<h2>Examples</h2>
<p>This section contains a few minimal code examples that show how a timing object may be used.</p>
<section>
<h3>Query</h3>
<pre class="example highlight" title="Read the current position of a timing object">
// Create timing object at position 2
// (note velocity and acceleration default to 0)
var to = new TimingObject({ position: 2.0 });
// Read and report current value to the console
// (renders "pos:2 vel:0, acc:0" in this example)
var vector = to.query();
console.log("pos:" + vector.position +
" vel:" + vector.velocity +
" acc:" + vector.acceleration);
</pre>
</section>
<section>
<h3>Update</h3>
<pre class="example highlight" title="Play and pause buttons to control a timing object">
// Pointers to "play" and "pause" buttons in the DOM
var playbutton, pausebutton;
// Start/Stop timing object when buttons are clicked
var to = new TimingObject();
playbutton.onclick = function () {
to.update({ velocity: 1.0 });
};
pausebutton.onclick = function () {
to.update({ velocity: 0.0 });
};
</pre>
</section>
<section>
<h3>Polling</h3>
<p>By querying the timing object repeatedly we can refresh time sensitive UI and demonstrate that the value of the timing object is changing predictably in time.</p>
<pre class="example highlight" title="Poll and render position periodically">
var elem; // DOM Element
var to = new TimingObject();
setInterval(function () {
elem.innerHTML = to.query().position;
}, 100);
</pre>
<p>Alternatively, use the built-in <i>timeupdate</i> event (fixed frequency).</p>
<pre class="example highlight" title="Render position periodically based on timeupdate event">
var elem; // DOM Element
var to = new TimingObject();
var to.addEventListener("timeupdate", function (e) {
elem.innerHTML = to.query().position;
});
</pre>
</section>
<section>
<h3>Update Event</h3>
<p>Update operations cause abrupt changes to the timing object. Register a handler to be notified.</p>
<pre class="example highlight" title="Report when a timing object stops moving">
var elem; // DOM Element
var to = new TimingObject();
to.addEventListener("update", function (e) {
var vector = to.query();
if (vector.velocity === 0.0 && vector.acceleration === 0.0) {
elem.innerHTML = "I'm not moving!";
} else {
elem.innerHTML = "I'm moving!";
}
});
// Make timing object move and then stop it
to.update({ velocity: 5, acceleration: 1 });
to.update({ velocity: 0, acceleration: 0 });
</pre>
</section>
<section>
<h3>Connect to a media element</h3>
<p>
A media element connected to a timing object will provide media playback precisely time-aligned with that timing object. In essence, the media element becomes a slave to the timing object. Pausing the timing object implies pausing the media element, etc.
</p>
<pre class="example highlight" title="Use timing object to control a video">
var video; // Pointer to a video element in the DOM
var to = new TimingObject();
video.timingsrc = to; // Video now directed by timing object
// Start timing object (video seeks and starts by implication)
to.update({ position: 5.0, velocity: 1.0 });
</pre>
</section>
<section>
<h3>Connect to a timing text track</h3>
<p>A timing text track connected to a timing object will provide enter/exit events for timed data, precisely time-aligned with that timing object. In essence, the timing text track becomes a slave to the timing object. Pausing the timing object implies pausing the timing text track, etc. </p>
<pre class="example highlight" title="Play simple timed data">
var elem; // DOM element
var to = new TimingObject();
// Create timed data
var track = new TimingTextTrack("metadata");
var cue = new DataCue(12.783, 13.612, "dog bark");
track.addCue(cue);
cue.addEventListener("enter", function () {
elem.innerHTML = "Dog is barking";
});
cue.addEventListener("exit", function () {
elem.innerHTML = "Dog is silent";
});
track.timingsrc = to; // track directed by timing object
to.update({ velocity: 1.0 }); // start playing timed data
</pre>
</section>
<section>
<h3>Connect to a timing provider</h3>
<p>A timing object may take its input from a TimingProvider object provided by some third-party provider (or developed by the app developer). TimingProvider objects will typically act as proxies to online timing resource, thus enabling cross-device synchronization.</p>
<pre class="example highlight" title="Connect to a TimingProvider object">
// TimingProvider object
// (constructor and parameters are provider-specific)
var tp;
// Create timing object associated with timing provider source
var to = new TimingObject(tp);
var to.addEventListener("timeupdate", function (e) {
var vector = to.query();
console.log("pos:" + vector.position +
" vel:" + vector.velocity +
" acc:" + vector.acceleration);
});
</pre>
</section>
</section>
<!-- TIMING OBJECT -->
<section>
<h2>Timing Object</h2>
<p>
A <dfn lt="timing object|timing objects">timing object</dfn> is an object that exposes a <a>timing resource</a> represented by a <a>state vector</a> to a Web application.
</p>
<p>
A <a>timing object</a> can have a <dfn>timing provider source</dfn>, which is a <code><a href="#timing-provider-object">TimingProvider</a></code> object that encapsulates the logic needed to represent an <a>external timing resource</a>. The <a>timing provider source</a> is initialized once and for all when the <a>timing object</a> is created.
</p>
<p>
<<<<<<< HEAD
A <a>timing object</a> has an <a>internal clock</a> which is [[HR-TIME]]. If the <a>timing object</a> is associated with a <a>timing provider object</a>, the <a>timing object</a> additionally has an <dfn lt="clock skew">internal clock skew</dfn>. This represents the current estimate of the skew between the clock of the <a>timing object</a> and the clock employed by the <a>timing provider</a>. The <a lt="clock skew">internal clock skew</a> is provided by the <a>timing provider object</a>, and defined so that <var>clock<sub>timing provider</sub></var> = <var>clock<sub>user agent</sub></var> + <var>skew</var>. This equation is used by the <a>timing object</a> to convert timestamps between the timelines of the two clocks. The <a>timing object</a> must ensure monotonic behavior by, if necessary, applying skew changes gradually.
</p>
<p>
A <a>timing object</a> has an <dfn>internal vector</dfn> that represents the initial conditions of the current motion. The <a>internal vector</a> is used by the <code>query()</code> operation to calculate a snapshot <a>state vector</a> of the current motion. If the <a>timing object</a> is associated with a <a>timing provider object</a>, the <a>internal vector</a> is provided by the <a>timing provider</a> and therefore includes a timestamp value from the timeline of the <a>timing provider</a>.
=======
A <a>timing object</a> has an <dfn>internal clock</dfn> which is a monotonic clock. The <a>internal clock</a> is the <a>performance clock</a> if the <a>timing object</a> is not associated with a <a>timing provider object</a>. If the <a>timing object</a> is associated with a <a>timing provider object</a>, the <a>internal clock</a> is a <dfn>logical clock</dfn> that the <a>user agent</a> dynamically adjusts to follow the updates made by the <a>timing resource provider</a> to the <code>skew</code> property of the <a>timing provider object</a>. The <i>skew</i> is an estimation of the difference between the <a>timing resource provider</a> clock and the <a>performance clock</a>, so that <var>clock<sub>timing provider</sub></var> = <var>clock<sub>user agent</sub></var> + <var>skew</var>. The <a>user agent</a> must ensure the monotonicity of the <a>logical clock</a> by applying skew changes gradually, if necessary.
</p>
<p>
A <a>timing object</a> has an <dfn>internal vector</dfn> that represents the initial conditions of the current motion. The <a>internal vector</a> is used by the <code>query()</code> operation to calculate a snapshot <a>state vector</a> of the current motion. The <a>timing object</a> is said to be moving if the velocity and/or acceleration of its <a>internal vector</a> is non-zero. If the <a>timing object</a> is associated with a <a>timing provider object</a>, the <a>internal vector</a> is provided by the <a>timing resource provider</a> and therefore includes a timestamp value from the timeline of the <a>timing resource provider</a>.
>>>>>>> 7243da8282da0b75a6504e779f98ff42a5e488b5
</p>
<p>
A <a>timing object</a> has a <dfn>state</dfn> property that describes the operational state of the <a>timing object</a>. If the <a>timing object</a> is associated with a <a>timing provider object</a>, the operational <a>state</a> will reflect the state of the <a>timing provider</a>, and by implication the underlying communication link.
</p>
<p>
A <a>timing object</a> can have a <dfn>start position</dfn> and an <dfn>end position</dfn> that together define the <dfn>range</dfn> of positions for the <a>timing object</a>. Internally, the <a>timing object</a> must enforce this <a>range</a> restriction by updating its <a>internal vector</a> if a <a>range</a> violation occurs (at the correct moment). The <a>timing object</a> will maintain a <dfn>current range timeout</dfn> for this purpose, pointing to a scheduled timeout when set.
</p>
<p>A <a>timing object</a> implements the following interface:</p>
<pre class="idl">
[ Constructor (
optional TimingStateVectorUpdate vector,
optional unrestricted double startPosition,
optional unrestricted double endPosition),
Constructor (TimingProvider provider)]
interface TimingObject : EventTarget {
readonly attribute TimingObjectState readyState;
readonly attribute unrestricted double startPosition;
readonly attribute unrestricted double endPosition;
attribute EventHandler onreadystatechange;
attribute EventHandler onchange;
attribute EventHandler ontimeupdate;
attribute EventHandler onerror;
TimingStateVector query ();
Promise update (TimingStateVectorUpdate newVector);
};
</pre>
<div dfn-for="TimingObject" link-for="TimingObject">
<p>
The <dfn>startPosition</dfn> and <dfn>endPosition</dfn> attributes MUST respectively be set to the <a>start position</a> and <a>end position</a> that the <a>state vector</a> may take, if any, or <code>-Infinity</code> and <code>Infinity</code> otherwise.
</p>
<p>
The <dfn>readyState</dfn> attribute MUST be set to the current state of the <a>timing provider</a>. If the <a>timing object</a> represents an <a>internal timing resource</a>, this will typically always be <code>connecting</code> or <code>open</code>. The <a>readyState</a> attribute may take other values when the <a>timing object</a> represents an <a>external timing resource</a>.
</p>
</div>
<section>
<h3>Create a new timing object</h3>
<p>
When the <code><a>TimingObject</a></code> constructor that takes an optional vector, a start position and an end position is invoked, the <a>user agent</a> MUST run the following steps:
</p>
<ol>
<li>Let <var>timing</var> be a newly created <code><a>TimingObject</a></code>.</li>
<li>Let <var>t</var> be a fresh timestamp read from the <a>internal clock</a>, defining the time of creation.
<li>Let <var>vectorInit</var> be the four-tuple <code>(p, v, a, t)</code>, where <code>(p, v, a)</code> are from the constructors first argument, or <code>(0,0,0)</code> if no argument is provided.</li>
<li>Let <var>timing</var>'s <a>internal vector</a> be a newly constructed <code><a>TimingStateVector</a></code> that represents <var>vectorInit</var>.</li>
<li>Let <var>timing</var>'s <a>timing provider source</a> be null.</li>
<li>Let <var>timing</var>'s <a>start position</a> be the constructor's second argument or <code>-Infinity</code> if not given.</li>
<li>Let <var>timing</var>'s <a>end position</a> be the constructor's third argument or <code>Infinity</code> if not given.</li>
<li>If <var>timing</var>'s <a>range</a> does not <a lt="covers">cover</a> the position of the <a>internal vector</a>:
<ol>
<li>Let <var>timing</var>'s <a>internal vector</a>'s position be <a>start position</a> or <a>end position</a>, whichever is closest</li>
<li>Let <var>timing</var>'s <a>internal vector</a>'s velocity and acceleration be <code>0.0</code> if the direction of the motion would make the position leave the <a>range</a> immediately.</li>
<li><a>Set the internal timeout</a> of <var>timing</var>.</li>
</ol>
</li>
<li>Let <var>timing</var>'s <a>state</a> be <code>open</code>.</li>
<li><a>Queue a task</a> to <a>fire a simple event</a> named <code>readystatechange</code> at <var>timing</var>.</li>
<li>Return <var>timing</var>.</li>
</ol>
<p>
When the <code><a>TimingObject</a></code> constructor that takes a <code><a>TimingProvider</a></code> is invoked, the <a>user agent</a> MUST run the following steps:
</p>
<ol>
<li>Let <var>provider</var> be the constructor's argument.</li>
<li>Let <var>timing</var> be a newly created <code><a>TimingObject</a></code> whose <a>timing provider source</a> is <var>provider</var>.</li>
<li>Let <var>timing</var>'s <a>start position</a> be <var>provider</var>'s <code>startPosition</code> property.</li>
<li>Let <var>timing</var>'s <a>end position</a> be <var>provider</var>'s <code>endPosition</code> property.</li>
<<<<<<< HEAD
<li>Let <var>timing</var>'s <a>state</a> be <var>provider</var>'s <code>readyState</code> property.</li>
=======
<li>Let <var>timing</var>'s <a>state</a> be <var>provider</var>'s <code>readyState</code> property and, if different from <code>connecting</code>, <a>queue a task</a> to <a>fire a simple event</a> named <code>readystatechange</code> at <var>timing</var>.</li>
>>>>>>> 7243da8282da0b75a6504e779f98ff42a5e488b5
<li>Let <var>timing</var>'s <a>internal vector</a> be <var>provider</var>'s <code>vector</code> property.</li>
<li>Let <var>timing</var>'s <a lt="clock skew">internal skew</a> be <var>provider</var>'s <code>skew</code> property.</li>
<li><a>Observe</a> <var>provider</var>.</li>
<li>
When an update to the <code>readyState</code> property is observed, run the following substeps:
<ol>
<li>If the transition from the current <a>state</a> of <var>timing</var> to the new value is in the list of <a>allowed state transitions</a>, let <var>timing</var>'s <a>state</a> be the new value. Otherwise, let <var>timing</var>'s <code>state</code> be <code>closed</code> and <a>stop observing</a> <var>provider</var>.</li>
<li>If the <code>error</code> property of <var>provider</var> is not null, <a>queue a task</a> to <a>fire a simple event</a> named <code>error</code> at <var>timing</var>.</li>
<li><a>Queue a task</a> to <a>fire a simple event</a> named <code>readystatechange</code> at <var>timing</var>.</li>
</ol>
</li>
<li>
When an update to the <code>vector</code> property is observed, run the following substeps:
<ol>
<li>Let <var>timing</var>'s <a>internal vector</a> be the new value.</li>
<li><a>Queue a task</a> to <a>fire a simple event</a> named <code>change</code> at the <var>timing</var>.</li>
</ol>
</li>
<li>
<<<<<<< HEAD
When an update to the <code>skew</code> property is observed, run the following substeps:
<ol>
<li>Let <var>timing</var>'s <a lt="clock skew">internal skew</a> be the new value.</li>
<li>Run <a>Process skew change</a></li>
</ol>
=======
When an update to the <code>skew</code> property is observed, the <a>user agent</a> MUST adjust <var>timing</var>'s <a>logical clock</a>, gradually if necessary to preserve the monotonicity of the clock.
>>>>>>> 7243da8282da0b75a6504e779f98ff42a5e488b5
</li>
<li>Return <var>timing</var>.</li>
</ol>
<p>
When a <a>user agent</a> is required to <dfn>observe</dfn> an object and run specific steps when an update to a property is detected, it MUST start to monitor the changes made to that object in the background and run the given steps as soon as the requested change is observed.
</p>
<p>
When a <a>user agent</a> is required to <dfn>stop observing</dfn> an object, it MUST stop any monitoring that was running on that object in the background.
</p>
<p class="issue">
This <a lt="observe">observing</a> mechanism is meant to emulate the <code>Object.observe</code> method that is being proposed in EcmaScript 7 to simplify the <code><a>TimingProvider</a></code> interface and requirements set on a <a>timing resource provider</a>, as well as to work around the fact that <code><a>TimingProvider</a></code> cannot inherit <code><a>EventTarget</a></code>. The Multi-Device Timing Community Group welcomes feedback as to whether this approach is doable in practice.
</p>
<p class="issue">
Should the procedure detail how to apply <code>skew</code> changes gradually to preserve the monotonicity of the <a>logical clock</a> or should that rather be left as an implementation detail?
</p>
</section>
<section>
<h3>Process a query operation</h3>
<p>
The <dfn for="TimingObject">query</dfn> method returns a snapshot derived from the evaluation of <a>internal vector</a> against the current timestamp of the <a>internal clock</a>. When the method is invoked on a <a>timing object</a> <var>timing</var>, the <a>user agent</a> MUST run the following steps:
</p>
<ol>
<li>Let <var>timing</var> be a <code><a>TimingObject</a></code>.</li>
<li>If the <a>state</a> of <var>timing</var> is not <code>open</code>, throw new <code>InvalidStateError</code> and abort all further steps.</li>
<li>Let <var>t<sub>u</sub></var> be the reading of the <a>internal clock</a> of the useragent, defining the processing time of the operation.</li>
<li>Let (<var>p<sub>int</sub></var>, <var>v<sub>int</sub></var>, <var>a<sub>int</sub></var>, <var>t<sub>int</sub></var>) represent the <a>internal vector</a> of <var>timing</var>.</li>
<li>If the <a>timing provider source</a> of <var>timing</var> is null, let <var>d</var> be <code><var>t<sub>u</sub></var>-<var>t<sub>int</sub></var></code>.</li>
<li>If the <a>timing provider source</a> of <var>timing</var> is not null, let <var>d</var> be <code><a>translate_u2p</a>(<var>t<sub>u</sub></var>)-<var>t<sub>int</sub></var></code>.</li>
<li>Let <var>p</var> be <var>p<sub>int</sub></var> + <var>v<sub>int</sub></var> * <var>d</var> + 1/2 * <var>a<sub>int</sub></var> * <var>d</var><sup>2</sup></li>
<li>Let <var>v</var> be <var>v<sub>int</sub></var> + <var>a<sub>int</sub></var> * <var>d</var></li>
<li>Let <var>a</var> be <var>a<sub>int</sub></var></li>
<li>Let <var>result</var> be newly created <code><a>TimingStateVector</a></code> from four-tuple (<var>p</var>, <var>v</var>, <var>a</var>, <var>t<sub>u</sub></var>)
<li>Range violation is detected. If not <a>range</a> <a>covers</a> <var>p</var>. Run the following substeps:
<ol>
<li>Let <var>start</var> be <var>timing</var>'s <code>startPosition</code> property.</li>
<li>Let <var>end</var> be <var>timing</var>'s <code>endPosition</code> property.</li>
<li>Let <var>p<sub>modified</sub></var> be either <var>start</var> or <var>end</var>, whichever is closest to <var>p</var>.</li>
<li>Let <var>vector</var> be newly created <code>TimingStateVectorUpdate</code> that from three-tuple (<var>p<sub>modified</sub></var>, 0, 0).</li>
<li>Invoke <a for="TimingObject">update</a> method on <var>timing</var> with <var>vector</var> as parameter. <span class="issue"> Update method should only have local effects.</span>
</li>
<li>Let <var>result</var> be result from invoking <a for="TimingObject">query</a> method on <var>timing</var> (recursively).</li>
</ol>
</li>
<li>Return <var>result</var>.</li>
</ol>
</section>
<section>
<h3>Process an update operation</h3>
<p>
The <dfn for="TimingObject">update</dfn> method sends a request for the <a>timing object</a> to update its current motion based on the provided <a>state vector</a>, or, if the <a>timing object</a> is associated with a <a>timing provider</a>, the request is sent to an <a>external timing resource</a> via the <a>timing provider source</a>. In both cases, a <code>Promise</code> that the update was taken into account is returned. The method supports <code>null</code> or <code>undefined</code> values for the provided <a>state vector</a> attributes. This provides a simple mechanism for tying movements together. The idea is to allow one aspect of the movement to be updated while preserving the others. For instance, <code>{position:null, velocity:value, acceleration:null}</code> means <i>update the velocity to the given value while preserving the current position and acceleration</i>. If all attributes of the <a>state vector</a> are <code>null</code> or <code>undefined</code>, the method is a noop and returns immediately.
</p>
<p>
When the <a for="TimingObject">update</a> method is invoked on a <a>timing object</a> <var>timing</var>, the <a>user agent</a> MUST run the following steps:
</p>
<ol>
<li>Let <var>timing</var> be a <code><a>TimingObject</a></code>.</li>
<li>If the <a>state</a> of <var>timing</var> is not <code>open</code>, return a new <code>Promise</code>, reject the promise with <code>InvalidStateError</code> and abort all further steps.</li>
<li>Let <var>newVector</var> be the method's first parameter.</li>
<li>If the <a>timing provider source</a> of <var>timing</var> is not null, run the following substeps, and abort the remaining steps:
<ol>
<li>Let <var>promise<sub>provider</sub></var> be the result of calling <code>update()</code> on the <a>timing provider source</a> object with <var>newVector</var> as parameter. If the call throws an exception, return a new <code>Promise</code>, reject the promise with the exception and abort all remaining steps. Similarly, if the call does not return a <code>Promise</code>, return a new <code>Promise</code>, reject the promise with a <code>TypeError</code> and abort all remaining steps.</li>
<li>Return <var>promise<sub>provider</sub></var>.</li>
</ol>
</li>
<li>Let <var>nowVector</var> be result from invoking <a for="TimingObject">query</a> method on <var>timing</var>.</li>
<li>Let <var>intVector</var> be <var>timing</var>'s' <a>internal vector</a>.</li>
<li>Let (<var>p<sub>new</sub></var>, <var>v<sub>new</sub></var>, <var>a<sub>new</sub></var>) be the three-tuple represented by <var>newVector</var>.</li>
<li>Let (<var>p<sub>now</sub></var>, <var>v<sub>now</sub></var>, <var>a<sub>now</sub></var>, <var>t<sub>now</sub></var>) be the four-tuple represented <var>nowVector</var>.</li>
<li>Let (<var>p<sub>int</sub></var>, <var>v<sub>int</sub></var>, <var>a<sub>int</sub></var>, <var>t<sub>int</sub></var>) be the four-tuple represented <var>intVector</var>.</li>
<li>Let <var>p</var> be <var>p<sub>new</sub></var>, or <var>p<sub>now</sub></var> if <var>p<sub>new</sub></var> is <code>null</code> or <code>undefined</code>.
<li>Let <var>v</var> be <var>v<sub>new</sub></var>, or <var>v<sub>now</sub></var> if <var>v<sub>new</sub></var> is <code>null</code> or <code>undefined</code>.
<li>Let <var>a</var> be <var>a<sub>new</sub></var>, or <var>a<sub>now</sub></var> if <var>a<sub>new</sub></var> is <code>null</code> or <code>undefined</code>.
<li>Avoid range violation on update. Run the following substeps:
<ol>
<li>If not <a>range</a> <a>covers</a> <var>p</var> throw new <code>IllegalValueError</code> and abort any further steps.</li>
<li>Let <var>start</var> be <var>timing</var>'s <code>startPosition</code> property.</li>
<li>If <code><var>p</var> = start && (<var>v</var> < 0|| (<var>v</var> = 0 && <var>a</var> < 0))</code> throw new <code>IllegalValueError</code> and abort any further steps.</li>
<li>Let <var>end</var> be <var>timing</var>'s <code>endPosition</code> property.</li>
<li>If <code><var>p</var> = end && (<var>v</var> > 0 || (<var>v</var> = 0 && <var>a</var> > 0))</code> throw new <code>IllegalValueError</code> and abort any further steps.</li>
</ol>
</li>
<li>Let <var>vector</var> be a newly created <code><a>TimingStateVector</a></code> that represents the four-tuple (<var>p</var>, <var>v</var>, <var>a</var>, <var>t<sub>now</sub></var>).</li>
<li>Set the <a>internal vector</a> of <var>timing</var> to <var>vector</var>.</li>
<li><a lt="set the internal timeout">Set the internal timeout</a> of <var>timing</var>.</li>
<li><a>Queue a task</a> to <a>fire a simple event</a> named <code>change</code> at <var>timing</var>.</li>
<li>Resolve <var>promise</var>.</li>
</ol>
</section>
<section>
<h3>Set the internal timeout</h3>
<p>
If <a>timing object</a>'s properties <code>startPosition</code> and <code>endPosition</code> are specified, e.g. <code>[0,123]</code>, the timing object must schedule a future <code>update</code> operation on itself, to ensure that the <a>range</a> is not violated.
<p>
<p>
When the <a>user agent</a> is required to <dfn>set the internal timeout</dfn> of a <a>timing object</a>, it must run the following steps:
</p>
<ol>
<li>Let <var>timing</var> be a <code><a>TimingObject</a></code>.</li>
<li>If the <a>current range timeout</a> is not null, cancel the timeout and set the <a>current range timeout</a> to null.</li>
<li>Let <var>startPos</var> be <var>timing</var>'s <code>startPosition</code>.</li>
<li>Let <var>endPos</var> be <var>timing</var>'s <code>endPosition</code>.</li>
<li>Given the current motion, let <var>endpoint</var> be the first of <var>startPos</var> or <var>endPos</var> to be violated first, if any, and let <var>t</var> be the time when this will occur according to the <a>internal clock</a>.</li>
<li>If <var>endpoint</var> is null, abort all further steps.</li>
<li>Let <var>vector</var> be the <code>TimingStateVector</code> represented by four-tuple (<var>endpoint</var>, 0, 0, t).</li>
<li>Set the <a>current range timeout</a> to a newly created timeout to execute an <code>update</code> operation on <var>timing</var> with <var>vector</var> as parameter, at the moment when the <a>internal clock</a> reaches <var>t</var>.</li>
</ol>
</section>
<section>
<h3>Cover a position</h3>
<p>
When the <a>user agent</a> is required to evaluate whether a <a>range</a> composed of possibly infinite lower and upper bounds <dfn>covers</dfn> a provided value, the <a>user agent</a> MUST run the following steps:
</p>
<ol link-for="TimingObject">
<li>Let <var>value</var> be the position to evaluate.</li>
<li>If <var>value</var> is smaller than the <a>range</a>'s lower bound, return <code>false</code>, and abort these steps.</li>
<li>If <var>value</var> is greater than the <a>range</a>'s upper bound, return <code>false</code>, and abort these steps.</li>
<li>Return true.</li>
</ol>
</section>
<section>
<h3>Process Skew Change</h3>
<p>
<dfn>Process skew change</dfn>
</p>
</section>
<section>
<h3>Translate u2p</h3>
<p>
<dfn lt="translate_u2p"><code><var>t<sub>p</sub></var> = translate_u2p(<var>t<sub>u</sub></var>)</code></dfn> translates a timestamp from the timeline of the <a>user agent</a> (u) to the timeline of the <a>timing provider</a> (p).
</p>
</section>
<section>
<h3>Translate p2u</h3>
<p>
<dfn lt="translate_p2u"><code><var>t<sub>u</sub></var> = translate_p2u(<var>t<sub>p</sub></var>)</code></dfn> translates a timestamp from the timeline of the <a>timing provider</a> (p) to the timeline of the <a>user agent</a> (u).
</p>
</section>
<section>
<h3>Connection states</h3>
<p>
The connection with the <a>timing resource</a> that the <a>timing object</a> represents may take the following states:
</p>
<dl title="enum TimingObjectState" class="idl">
<dt>connecting</dt>
<dd>The <a>timing object</a> is attempting to establish a connection with the <a>timing resource</a> it represents. This is the initial state when a new <code><a>TimingObject</a></code> is created. This state is also used when a <code><a>TimingProvider</a></code> object is associated with the <code><a>TimingObject</a></code>.</dd>
<dt>open</dt>
<dd>The connection with the <a>timing resource</a> is established and communication is possible.</dd>
<dt>closing</dt>
<dd>The procedure to close down the connection with the <a>timing resource</a> has started.</dd>
<dt>closed</dt>
<dd>The connection with the <a>timing resource</a> has been closed or could not be established.</dd>
</dl>
<p>
The <dfn>allowed state transitions</dfn> are:
</p>
<ul>
<li>from <code>connecting</code> to any of the other states;</li>
<li>from <code>open</code> to <code>closing</code> and <code>closed</code>;</li>
<li>from <code>closing</code> to <code>closed</code>.</li>
</ul>
</section>
<section>
<h3>Event handlers</h3>
<p>The following are the <a>event handlers</a> (and their corresponding <a>event handler event types</a>) that MUST be supported as attributes by a <a>TimingObject</a> object. All events use the <a>Event</a> interface.</p>
<table dfn-for="TimingObject">
<thead>
<tr>
<th>Event handler</th>
<th>Event handler event type</th>
<th>Fired</th>
</tr>
</thead>
<tbody>
<tr>
<td><dfn><code>onchange</code></dfn></td>
<td><dfn><code>change</code></dfn></td>
<td>The <a>internal vector</a> is changed. Fired after the <code>update()</code> method has returned, or when an update is received from the <a>external timing resource</a>.</td>
</tr>
<tr>
<td><dfn><code>onreadystatechange</code></dfn></td>
<td><dfn><code>readystatechange</code></dfn></td>
<td>The <code>readyState</code> attribute changed.<br/></td>
</tr>
<tr>
<td><dfn><code>ontimeupdate</code></dfn></td>
<td><dfn><code>timeupdate</code></dfn></td>
<td>Fires periodically with fixed frequency 5Hz, except when timing object is paused. This is intended as a shorthand alternative for setting up a polling-loop with setInterval, or as an emulation of the pulse-based timing model that programmers are currently used to.</td>
</tr>
<tr>
<td><dfn><code>onerror</code></dfn></td>
<td><dfn><code>error</code></dfn></td>
<td>Fired when an operation on the <a>timing object</a> cannot complete for some reason, (e.g. because of a loss of connection with the <a>timing resource</a>).</td>
</tr>
</tbody>
</table>
</section>
</section>
<!-- TimingProvider -->
<section>
<h3>Timing Provider Object</h3>
<p>
A <dfn lt="timing provider object|timing provider objects">timing provider object</dfn> is an object exposed by a <a>timing resource provider</a> that encapsulates logic is necessary to associate a <a>timing object</a> with an <a>external timing resource</a>.
</p>
<p>
The concept is introduced in order to leave space open for innovation among online timing providers. The purpose is to decouple the <a>user agent</a> from any particular <a>timing resource provider</a>: third parties may provide different implementations of <a>timing provider objects</a> in JavaScript, to which <a>timing objects</a> may be connected. In particular, this means that the protocols and logic used to identify, create or destroy an <a>external timing resource</a>, synchronize clocks and propagate <a>state vectors</a> to connected user agents, are up to the <a>timing resource provider</a>. Similarly, a <a>timing resource provider</a> may require Web applications or users to authenticate themselves before they grant them access to a particular <a>timing resource</a>.
</p>
<p>
In practice, a Web application willing to use a particular <a>timing resource provider</a> needs to load the corresponding JavaScript library provided by this <a>timing resource provider</a>, create a <a>timing provider object</a> and pass that object to the <a>timing object</a> constructor.
</p>
<p>
The <a>TimingProvider</a> interface allows the <a>timing object</a> to exercise control over the <a>timing provider object</a>, as well as be notified of state changes as soon as they occur, in particular <a href="#state-vector-synchronization">state vectors</a> and <a href="#clock-synchronization">clock skew estimates</a>.</p>
<p>
The <dfn>skew</dfn> specifies how timestamps may be translated between the timeline of the <a>performance clock</a> and that used by the <a>timing resource provider</a>. In the case of <a>online timing resources</a>, the <a>skew</a> is a floating estimate (due to variance in network latency and relative clock drift over time). The <code>query</code> operation on the <a>timing object</a> should always be resolved using a fresh <a>skew</a> estimate received from the <a>timing provider object</a>. <a>Skew</a> is defined by the following equation (where <var>clock<sub>user agent</sub></var> is the <a>performance clock</a>):
</p>
<p>
<var>clock<sub>timing provider</sub></var> = <var>clock<sub>user agent</sub></var> + <var>skew</var>
</p>
<p>
A <a>timing provider object</a> implements the following interface:
</p>
<pre class="idl">
callback interface TimingProvider {
readonly attribute TimingStateVector vector;
readonly attribute unrestricted double startPosition;
readonly attribute unrestricted double endPosition;
readonly attribute DOMString readyState;
readonly attribute unrestricted double skew;
Promise update (TimingStateVectorUpdate newVector);
};
</pre>
<div dfn-for="TimingProvider">
<p>
The <dfn>vector</dfn> attribute MUST be set to the <a>state vector</a> that represents the initial conditions of the current motion.
</p>
<p>
The <dfn>startPosition</dfn> attribute MUST be set to the lower bound that constrains the position of the <a>state vector</a>, if any.
</p>
<p>
The <dfn>endPosition</dfn> attribute MUST be set to the upper bound that constrains the position of the <a>state vector</a>, if any.
</p>
<p>
The <dfn>readyState</dfn> attribute MUST be set to the current state of the connection with the <a>timing resource</a>.
</p>
<p>
The <dfn>skew</dfn> attribute MUST be set to the current estimate of the skew.
</p>
</div>
<section>
<h3>Process an update operation</h3>
<p>
The <dfn for="TimingProvider">update</dfn> method sends a request to the <a>timing resource</a> to have it update the <a>external timing resource</a>, based on the provided <a>state vector</a>, and returns a <code>Promise</code> that the update was processed by the <a>timing resource provider</a> (see the <a for="TimingObject">update</a> method of <a>TimingObject</a> objects for more details). When the method is invoked on a <a>timing provider object</a> <var>provider</var>, the <a>timing resource provider</a> MUST run the following steps:
</p>
<ol>
<li>Let <var>promise</var> be a new <code>Promise</code>.</li>
<li>Return <var>promise</var> and run the following steps in parallel.</li>
<li>Run whatever logic is necessary to pass the update request to the <a>external timing resource</a> that <var>provider</var> represents.</li>
<li>If this logic succeeds, resolve <var>promise</var>. Otherwise reject <var>promise</var> with an error.</li>
</ol>
</section>
<section>
<h3>Report new conditions of the current motion</h3>
<p>
When the <a>timing resource provider</a> needs to report an update to the <a>state vector</a> (position, velocity or acceleration) of the <a>external timing resource</a> that a <code><a>TimingProvider</a></code> object encapsulates, it MUST set its <a for="TimingProvider">vector</a> property to a new <code><a>TimingStateVector</a></code> that represents the new conditions.
</p>
</section>
<section>
<h3>Report a state change</h3>
<p>
When the <a>timing resource provider</a> needs to report a change of connection state with the <a>external timing resource</a> that a <code><a>TimingProvider</a></code> object encapsulates, it MUST set its <a for="TimingProvider">readyState</a> property to the new value.
</p>
</section>
<section>