Skip to content

Commit 098b399

Browse files
Spec first version (#1)
This PR implements the first version of the spec, which includes integrations with HTMLMediaElements and Web Audio AudioContexts.
1 parent d4ea8ee commit 098b399

File tree

1 file changed

+120
-6
lines changed

1 file changed

+120
-6
lines changed

index.bs

Lines changed: 120 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,138 @@ Shortname: iframe-media-pausing
44
Level: 1
55
Status: w3c/UD
66
Group: wicg
7-
Repository: WICG/iframe-media-pausing
7+
Repository: wicg/iframe-media-pausing
88
URL: https://github.com/WICG/iframe-media-pausing
99
Editor: Gabriel Santana Brito, Microsoft https://microsoft.com/, gabrielbrito@microsoft.com, https://github.com/gabrielsanbrito
1010
Abstract: This specification defines a new permission policy that allows the
1111
user-agent to pause media playback in iframes which are not visible to
1212
the user.
1313
Complain About: accidental-2119 yes, missing-example-ids yes
14-
Markup Shorthands: markdown yes, css no
14+
Default Biblio Status: current
15+
Markup Shorthands: markdown yes, css no, dfn yes, markup yes
16+
</pre>
17+
18+
<pre class="anchors">
19+
spec: webaudio; urlPrefix: https://webaudio.github.io/web-audio-api/;
20+
type: dfn; text: allowed to start; url: #allowed-to-start
21+
spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/;
22+
type: dfn; text: allowed to play; url: media.html#allowed-to-play
23+
type: dfn; text: content document; url: document-sequences.html#concept-bcc-content-document
24+
type: dfn; text: eligible for autoplay; url: media.html#eligible-for-autoplay
25+
type: dfn; text: internal pause steps; url: media.html#internal-pause-steps
26+
type: dfn; text: nested browsing context; url: document-sequences.html#nested-browsing-context
1527
</pre>
1628

1729
# Introduction # {#intro}
1830

1931
<em>This section is non-normative.</em>
2032

21-
Web applications that host embedded media content via iframes may wish to respond to application input by temporarily hiding the media content. These applications may not want to unload the entire iframe when it's not rendered since it could generate user-perceptible performance and experience issues when showing the media content again. At the same time, the user could have a negative experience if the media continues to play and emit audio when not rendered. This proposal aims to provide web applications with the ability to control embedded media content in such a way that guarantees their users have a good experience when the iframe's render status is changed.
33+
Web applications that host embedded media content via iframes may wish to respond to application input by temporarily hiding the media content.
34+
These applications may not want to unload the entire iframe when it's not rendered since it could generate user-perceptible performance and iframe state loss issues when showing the media content again.
35+
At the same time, the user could have a negative experience if the media continues to play and emit audio when not rendered.
36+
This proposal aims to provide web applications with the ability to control embedded media content in such a way that guarantees their users have a good experience when the iframe's render status is changed.
2237

2338
## Goals ## {#goals}
2439

25-
Propose a mechanism to allow embedder documents to limitedly control embedded iframe media playback based on whether the embedded iframe is rendered or not:
26-
* When the iframe is not rendered, the embedder is able to pause the iframe media playback; and
27-
* When the iframe becomes rendered again, the embedder is able to resume the iframe media playback.
40+
Propose a mechanism to allow embedder documents to limitedly control embedded
41+
iframe media playback based on whether the embedded iframe is rendered or not:
42+
* When the iframe is not rendered, the embedder is able to pause the iframe's media playback; and
43+
* When the iframe becomes rendered again, the embedder is able to resume the iframe media playback.
44+
45+
# API # {#api}
46+
47+
Control over media playback in [=child navigables=] in response to changes to their [=container=]'s visibility is relevant for user experience and performance reasons.
48+
Although simply disposing of the [=navigable container=] when not rendered would also achieve the same result (no audible media playback), it could lead to user-perceptible performance issues when the [=navigable container=] is rendered again, since it would need to be recreated from scratch.
49+
Moreover, disposing of the context could also lead to loss of state that the user might expect to be preserved - e.g. form data.
50+
51+
This specification defines a new [=policy-controlled feature=] identified by the token "<dfn export><code>media-playback-while-not-visible</code></dfn>" that controls whether a {{Document}} is allowed to play media while it is not [=being rendered=].
52+
The [=default allowlist=] for this policy is "[=default allowlist/*=]", meaning that documents are allowed to play media while not rendered unless the policy is explicitly disabled.
53+
54+
To determine if a {{Document}} |document| is <dfn>allowed to play media while not rendered</dfn>, run the following steps:
55+
56+
1. If |document| is [=/allowed to use=] the "<a><code>media-playback-while-not-visible</code></a>" feature, then return true.
57+
1. Return false otherwise.
58+
59+
## Usage example ## {#usage-example}
60+
61+
<div id="iframe-example" class="example">
62+
<p>
63+
Using the <code>media-playback-while-not-visible</code> permission policy to prevent an <{iframe}> and all of its children from playing media when the iframe is not [=being rendered=].
64+
</p>
65+
<pre>
66+
&lt;iframe src="https://foo.media.com" allow="media-playback-while-not-visible 'none'"&gt;&lt;/iframe&gt;
67+
</pre>
68+
</div>
69+
70+
<div id="application-example" class="example">
71+
<p>
72+
To disable the <code>media-playback-while-not-visible</code> permission policy for an entire web application, the application can send the HTTP response header below. Doing so will disable the permission policy for the application's top-level {{Document}} and for all of the embedded <{iframe}>'s.
73+
</p>
74+
<pre>
75+
Permissions-Policy: media-playback-while-not-visible=()
76+
</pre>
77+
</div>
78+
79+
# Integration with other specifications # {#integration}
80+
81+
There are several ways to render audible media content on the web, which means that this specification has points of contact with other specifications.
82+
The "<a><code>media-playback-while-not-visible</code></a>" strictly interacts with audible media content in two scenarios:
83+
84+
1. When the iframe is not rendered and it attempts to play audible media; and
85+
2. When the iframe is currently playing audible media and stops [=being rendered=] during playback.
86+
87+
The following sections describe how the "<a><code>media-playback-while-not-visible</code></a>" permission policy integrates with other specifications.
88+
89+
## HTMLMediaElement ## {#html-media-element-integration}
90+
91+
Let |mediaElement| be an {{HTMLMediaElement}}. Let {{Document}} |document| be the |mediaElement|'s [=node document=]. Let [=/Navigable=] |navigable| be the [=node navigable=] of |mediaElement|. Let |navigableContainer| be the [=container=] of |navigable|.
92+
93+
Note: |navigableContainer| is null if |navigable| is a [=/top-level traversable=].
94+
95+
Amend the definition of [=allowed to play=] so that |mediaElement| is also not [=allowed to play=] if all the following conditions are met:
96+
- |navigableContainer| is not null;
97+
- |document| is not [=allowed to play media while not rendered=]; and
98+
- |navigableContainer| is not [=being rendered=].
99+
100+
Note: Calling {{HTMLMediaElement/play()}} on |mediaElement| while it is not [=allowed to play=] will return a promise rejected with a "{{NotAllowedError}}" {{DOMException}}.
101+
102+
When |navigableContainer| is not null and stops [=being rendered=]:
103+
104+
1. If |document| is not [=allowed to play media while not rendered=]:
105+
1. Run the [=internal pause steps=] on |mediaElement|.
106+
107+
## Web Audio ## {#web-audio-integration}
108+
109+
Let |audioContext| be an {{AudioContext}}. Let {{Document}} |document| be the |audioContext|'s [=relevant global object=]'s [=associated Document=]. Let |navigable| be [=/Navigable=] whose [=active document=] is |document|. Let |navigableContainer| be the [=navigable container=] whose [=content document=] is |document|.
110+
111+
Amend the definition of [=allowed to start=] so that |audioContext| is also not [=allowed to start=] if all the following conditions are met:
112+
- |navigableContainer| is not null;
113+
- |document| is not [=allowed to play media while not rendered=]; and
114+
- |navigableContainer| is not [=being rendered=].
115+
116+
Note: If |audioContext| is created while |navigableContainer| is not [=being rendered=], it will be initialized in the {{AudioContextState/suspended}} state. Furthermore, attempting to call {{AudioContext/resume()}} on |audioContext| while |navigableContainer| is not [=being rendered=] will return a promise rejected with {{InvalidStateError}} and transition |audioContext| to the {{AudioContextState/interrupted}} state.
117+
118+
When |navigableContainer| is not null and stops [=being rendered=]:
119+
120+
1. If |document| is not [=allowed to play media while not rendered=]:
121+
1. If |audioContext| {{BaseAudioContext/state}} is {{AudioContextState/running}}:
122+
1. {{AudioContext/interruption-start|Start an interruption}} on |audioContext|.
123+
124+
When |navigableContainer| is not null and starts [=being rendered=] again:
125+
126+
1. If |document| is not [=allowed to play media while not rendered=]:
127+
1. If |audioContext| {{BaseAudioContext/state}} is {{AudioContextState/interrupted}}:
128+
1. {{AudioContext/interruption-end|End the interruption}} on |audioContext|.
129+
130+
## Autoplay ## {#autoplay-integration}
131+
132+
Let |mediaElement| be an {{HTMLMediaElement}}. Let {{Document}} |document| be the |mediaElement|'s [=node document=]. Let [=/Navigable=] |navigable| be the [=node navigable=] of |mediaElement|. Let |navigableContainer| be the [=container=] of |navigable|.
133+
134+
Amend the definition of [=eligible for autoplay=] so that |mediaElement| is also not [=eligible for autoplay=] if all the following conditions are met:
135+
- |navigableContainer| is not null;
136+
- |document| is not [=allowed to play media while not rendered=]; and
137+
- |navigableContainer| is not [=being rendered=].
138+
139+
Moreover, if |mediaElement| is currently playing because of autoplay and |navigableContainer| stops [=being rendered=], the user-agent MUST run the [=internal pause steps=] on |mediaElement|. When |navigableContainer| starts [=being rendered=] again, |mediaElement| MUST remain paused until playback is explicitly resumed.
140+
141+
The "<a><code>media-playback-while-not-visible</code></a>" permission policy MUST NOT affect autoplay behavior if |navigableContainer| is currently [=being rendered=].

0 commit comments

Comments
 (0)