Skip to content

Commit

Permalink
Add position state to the spec
Browse files Browse the repository at this point in the history
  • Loading branch information
beccahughes committed Apr 11, 2019
1 parent 3d0f74b commit e2a1355
Showing 1 changed file with 178 additions and 5 deletions.
183 changes: 178 additions & 5 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ urlPrefix: https://www.w3.org/TR/appmanifest/; spec: appmanifest
text: image object; url: #dfn-image-object
urlPrefix: https://heycam.github.io/webidl/
type: exception
text: DataError
text: TypeError
urlPrefix: https://tc39.github.io/ecma262/#sec-object.; type: dfn
text: freeze
Expand Down Expand Up @@ -618,6 +619,86 @@ conforming IDL fragments, as described in the Web IDL specification. [[!WEBIDL]]
</ol>
</p>
</section>

<section>
<h3 id='position-state'>Position State</h3>

<p>
A user agent MAY display the <a>current playback position</a> and <a>duration</a>
of a media session in the platform UI depending on platform conventions. The
<dfn>position state</dfn> is the combination of the following:
<ul>
<li>
The <dfn>duration</dfn> of the media in seconds.
</li>
<li>
The <dfn>playback rate</dfn> of the media. It is a coefficient.
</li>
<li>
The <dfn>last reported playback position</dfn> of the media. This is the
playback position of the media in seconds when the <a>position state</a>
was created.
</li>
</ul>
</p>

<p>
The <a>position state</a> is represented by a {{MediaPositionState}} which MUST
always be stored with the <dfn>last position updated time</dfn>. This is the
time the <a>position state</a> was last updated in seconds.
</p>

<p>
The RECOMMENDED way to determine the <a>position state</a> is to monitor the
media elements whose node document's browsing context is the
<a>browsing context</a>.
</p>

<p>
The <dfn>actual playback rate</dfn> is a coefficient computed in the following way:
<ul>
<li>
If the <a>playback rate</a> is not null, then return this.
</li>
<li>
If the <a>actual playback state</a> is <a enum-value
for="MediaSessionPlaybackState">playing</a>, then return one.
</li>
<li>
Return zero.
</li>
</ul>
</p>

<p>
The <dfn>current playback position</dfn> in seconds is computed in the following
way:
<ul>
<li>
Set <var>time elapsed</var> to the system time in seconds minus the
<a>last position updated time</a>.
</li>
<li>
Mutliply <var>time elapsed</var> with <var>actual playback rate</var>.
</li>
<li>
Set <var>position</var> to <var>time elapsed</var> added to
<a>last reported playback position</a>.
</li>
<li>
If <var>position</var> is less than zero, return zero.
</li>
<li>
If <var>position</var> is greater than <a>duration</a>, return <a>duration</a>.
</li>
<li>
Return <var>position</var>.
</li>
</ul>
</p>

</section>

</section>

<h2 id="the-mediasession-interface">The {{MediaSession}} interface</h2>
Expand Down Expand Up @@ -654,6 +735,8 @@ interface MediaSession {
attribute MediaSessionPlaybackState playbackState;

void setActionHandler(MediaSessionAction action, MediaSessionActionHandler? handler);

void setPositionState(MediaPositionState? state);
};
</pre>

Expand Down Expand Up @@ -706,12 +789,15 @@ interface MediaSession {
attribute represents the <dfn>declared playback state</dfn> of the <a>media
session</a>, by which the session declares whether its <a>browsing context</a>
is playing media or not. The initial value is <a enum-value
for="MediaSessionPlaybackState">none</a>. On setting, the user agent MUST set
the IDL attribute to the new value if it is a valid
{{MediaSessionPlaybackState}} value. On getting, the user agent MUST return
the last valid value that was set. The {{MediaSession/playbackState}}
for="MediaSessionPlaybackState">none</a>. The {{MediaSession/playbackState}}
attribute is a hint for the user agent to determine whether the <a>browsing
context</a> is playing or paused.
context</a> is playing or paused. On getting, the user agent MUST return
the last valid value that was set. On setting, the user agent MUST set the
IDL attribute to the new value if it is a valid {{MediaSessionPlaybackState}}
value. If the attribute was updated through the
<a method for=MediaSession>setPositionState()</a> method then it should clear
the <a>playback rate</a> and update the <a>position state</a> and
<a>last position updated time</a>.
</p>

<p class=note>
Expand Down Expand Up @@ -748,6 +834,39 @@ interface MediaSession {
<var>action</var> and <var>handler</var> on the {{MediaSession}}.
</p>

<p>
The <dfn method for=MediaSession>setPositionState()</dfn> method, when
invoked MUST perform the following steps:

<ul>
<li>
If the <var>state</var> is null then clear the <a>position state</a>.
</li>
<li>
If the <a dict-member for="MediaPositionState">duration</a> is negative,
throw a <a exception>DataError</a>.
</li>
<li>
If the <a dict-member for="MediaPositionState">position</a> is negative
or greater than <a dict-member for="MediaPositionState">duration</a>,
throw a <a exception>DataError</a>. A null value should be ignored.
</li>
<li>
If the <a dict-member for="MediaPositionState">position</a> is zero then
set the {{MediaSession/playbackState}} attribute to <a enum-value
for="MediaSessionPlaybackState">paused</a>.
</li>
<li>
If the <a dict-member for="MediaPositionState">position</a> is a non-zero
integer then set the {{MediaSession/playbackState}} attribute to
<a enum-value for="MediaSessionPlaybackState">playing</a>.
</li>
<li>
Update the <a>position state</a> and <a>last position updated time</a>.
</li>
</ul>
</p>

<h2 id="the-mediametadata-interface">The {{MediaMetadata}} interface</h2>

<pre class="idl">
Expand Down Expand Up @@ -1016,6 +1135,34 @@ used to specify the {{MediaImage}} object's <a>MIME type</a>. It is a hint as to
the media type of the image. The purpose of this attribute is to allow a user
agent to ignore images of media types it does not support.

<h2 id="the-mediapositionstate-dictionary">The {{MediaPositionState}} dictionary</h2>

<pre class="idl">

dictionary MediaPositionState {
required double duration;
double playbackRate;
double position = 0.0;
};
</pre>

The {{MediaPositionState}} dictionary is a representation of the current playback
position associated with a {{MediaSession}} that can be used by user agents to
provide a user interface that displays the current playback position and duration.

The <dfn dict-member for="MediaPositionState">duration</dfn> <a>dictionary member</a>
is used to specify the <a>duration</a> in seconds. It should always be positive
and positive infinity can be used to indicate media that is unending.

The <dfn dict-member for="MediaPositionState">playbackRate</dfn> <a>dictionary member</a>
is used to specify the <a>playback rate</a>. It can be positive to represent forward
playback, negative to represent backwards playback or zero to represent media that
is paused.

The <dfn dict-member for="MediaPositionState">position</dfn> <a>dictionary member</a>
is used to specify the <a>last reported playback position</a> in seconds. It should
always be positive.

<h2 id="examples">Examples</h2>

<em>This section is non-normative.</em>
Expand Down Expand Up @@ -1186,6 +1333,32 @@ agent to ignore images of media types it does not support.
</pre>
</div>

<div class="example" id="example-media-position-state">
Setting <a>position state</a>:
<pre class="lang-javascript">
// Media is loaded, set the duration.
navigator.mediaSession.setPositionState({
duration: 60
});

// Media starts playing at the beginning.
navigator.mediaSession.playbackState = "playing";

// Media starts playing at 2x 10 seconds in.
navigator.mediaSession.setPositionState({
duration: 60,
playbackRate: 2,
position: 10
});

// Media is paused.
navigator.mediaSession.playbackState = "paused";

// Media is reset.
navigator.mediaSession.setPositionState(null);
</pre>
</div>

<h2 id="acknowledgments" class="no-num">Acknowledgments</h2>

The editors would like to thank Paul Adenot, Jake Archibald, Tab Atkins,
Expand Down

0 comments on commit e2a1355

Please sign in to comment.