diff --git a/index.bs b/index.bs index 729f3fe..1bb6730 100644 --- a/index.bs +++ b/index.bs @@ -4,24 +4,138 @@ Shortname: iframe-media-pausing Level: 1 Status: w3c/UD Group: wicg -Repository: WICG/iframe-media-pausing +Repository: wicg/iframe-media-pausing URL: https://github.com/WICG/iframe-media-pausing Editor: Gabriel Santana Brito, Microsoft https://microsoft.com/, gabrielbrito@microsoft.com, https://github.com/gabrielsanbrito Abstract: This specification defines a new permission policy that allows the user-agent to pause media playback in iframes which are not visible to the user. Complain About: accidental-2119 yes, missing-example-ids yes -Markup Shorthands: markdown yes, css no +Default Biblio Status: current +Markup Shorthands: markdown yes, css no, dfn yes, markup yes + + +
+spec: webaudio; urlPrefix: https://webaudio.github.io/web-audio-api/;
+    type: dfn; text: allowed to start; url: #allowed-to-start
+spec: HTML; urlPrefix: https://html.spec.whatwg.org/multipage/;
+    type: dfn; text: allowed to play; url: media.html#allowed-to-play
+    type: dfn; text: content document; url: document-sequences.html#concept-bcc-content-document
+    type: dfn; text: eligible for autoplay; url: media.html#eligible-for-autoplay
+    type: dfn; text: internal pause steps; url: media.html#internal-pause-steps
+    type: dfn; text: nested browsing context; url: document-sequences.html#nested-browsing-context
 
# Introduction # {#intro} This section is non-normative. -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. +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 iframe state loss 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. ## Goals ## {#goals} -Propose a mechanism to allow embedder documents to limitedly control embedded iframe media playback based on whether the embedded iframe is rendered or not: -* When the iframe is not rendered, the embedder is able to pause the iframe media playback; and -* When the iframe becomes rendered again, the embedder is able to resume the iframe media playback. \ No newline at end of file +Propose a mechanism to allow embedder documents to limitedly control embedded +iframe media playback based on whether the embedded iframe is rendered or not: +* When the iframe is not rendered, the embedder is able to pause the iframe's media playback; and +* When the iframe becomes rendered again, the embedder is able to resume the iframe media playback. + +# API # {#api} + +Control over media playback in [=child navigables=] in response to changes to their [=container=]'s visibility is relevant for user experience and performance reasons. +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. +Moreover, disposing of the context could also lead to loss of state that the user might expect to be preserved - e.g. form data. + +This specification defines a new [=policy-controlled feature=] identified by the token "media-playback-while-not-visible" that controls whether a {{Document}} is allowed to play media while it is not [=being rendered=]. +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. + +To determine if a {{Document}} |document| is allowed to play media while not rendered, run the following steps: + +1. If |document| is [=/allowed to use=] the "media-playback-while-not-visible" feature, then return true. +1. Return false otherwise. + +## Usage example ## {#usage-example} + +
+

+ Using the media-playback-while-not-visible permission policy to prevent an <{iframe}> and all of its children from playing media when the iframe is not [=being rendered=]. +

+
+        <iframe src="https://foo.media.com" allow="media-playback-while-not-visible 'none'"></iframe>
+  
+
+ +
+

+ To disable the media-playback-while-not-visible 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. +

+
+        Permissions-Policy: media-playback-while-not-visible=()
+  
+
+ +# Integration with other specifications # {#integration} + +There are several ways to render audible media content on the web, which means that this specification has points of contact with other specifications. +The "media-playback-while-not-visible" strictly interacts with audible media content in two scenarios: + +1. When the iframe is not rendered and it attempts to play audible media; and +2. When the iframe is currently playing audible media and stops [=being rendered=] during playback. + +The following sections describe how the "media-playback-while-not-visible" permission policy integrates with other specifications. + +## HTMLMediaElement ## {#html-media-element-integration} + +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|. + +Note: |navigableContainer| is null if |navigable| is a [=/top-level traversable=]. + +Amend the definition of [=allowed to play=] so that |mediaElement| is also not [=allowed to play=] if all the following conditions are met: +- |navigableContainer| is not null; +- |document| is not [=allowed to play media while not rendered=]; and +- |navigableContainer| is not [=being rendered=]. + +Note: Calling {{HTMLMediaElement/play()}} on |mediaElement| while it is not [=allowed to play=] will return a promise rejected with a "{{NotAllowedError}}" {{DOMException}}. + +When |navigableContainer| is not null and stops [=being rendered=]: + +1. If |document| is not [=allowed to play media while not rendered=]: + 1. Run the [=internal pause steps=] on |mediaElement|. + +## Web Audio ## {#web-audio-integration} + +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|. + +Amend the definition of [=allowed to start=] so that |audioContext| is also not [=allowed to start=] if all the following conditions are met: +- |navigableContainer| is not null; +- |document| is not [=allowed to play media while not rendered=]; and +- |navigableContainer| is not [=being rendered=]. + +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. + +When |navigableContainer| is not null and stops [=being rendered=]: + +1. If |document| is not [=allowed to play media while not rendered=]: + 1. If |audioContext| {{BaseAudioContext/state}} is {{AudioContextState/running}}: + 1. {{AudioContext/interruption-start|Start an interruption}} on |audioContext|. + +When |navigableContainer| is not null and starts [=being rendered=] again: + +1. If |document| is not [=allowed to play media while not rendered=]: + 1. If |audioContext| {{BaseAudioContext/state}} is {{AudioContextState/interrupted}}: + 1. {{AudioContext/interruption-end|End the interruption}} on |audioContext|. + +## Autoplay ## {#autoplay-integration} + +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|. + +Amend the definition of [=eligible for autoplay=] so that |mediaElement| is also not [=eligible for autoplay=] if all the following conditions are met: +- |navigableContainer| is not null; +- |document| is not [=allowed to play media while not rendered=]; and +- |navigableContainer| is not [=being rendered=]. + +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. + +The "media-playback-while-not-visible" permission policy MUST NOT affect autoplay behavior if |navigableContainer| is currently [=being rendered=].