Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add position state to the spec #210

Merged
merged 1 commit into from
May 2, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,83 @@ 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>actual playback state</a> is <a enum-value
for="MediaSessionPlaybackState">paused</a>, then return zero.
</li>
<li>
Return <a>playback rate</a>.
</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 <a>actual playback rate</a>.
</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 +731,8 @@ interface MediaSession {
attribute MediaSessionPlaybackState playbackState;

void setActionHandler(MediaSessionAction action, MediaSessionActionHandler? handler);

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

Expand Down Expand Up @@ -748,6 +827,33 @@ 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>TypeError</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>TypeError</a>.
</li>
<li>
If the <a dict-member for="MediaPositionState">playbackRate</a> is zero
throw a <a exception>TypeError</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 +1122,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;
beccahughes marked this conversation as resolved.
Show resolved Hide resolved
double playbackRate = 1.0;
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 without a defined end such as
live playback.

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 or negative to represent backwards playback. It should not be zero.

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>
beccahughes marked this conversation as resolved.
Show resolved Hide resolved

<em>This section is non-normative.</em>
Expand Down Expand Up @@ -1186,6 +1320,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