diff --git a/index.bs b/index.bs index 8a32fbf..d025061 100644 --- a/index.bs +++ b/index.bs @@ -14,7 +14,7 @@ Abstract: notification areas and on lock screens of mobile devices. !Participate: File an issue (open issues) !Participate: IRC: #whatwg on Freenode !Version History: https://github.com/whatwg/mediasession/commits -Ignored Vars: context, media +Ignored Vars: context, media, session Boilerplate: omit conformance, omit feedback-header @@ -155,35 +155,12 @@ urlPrefix: https://heycam.github.io/webidl/ This section is non-normative. -Media is used extensively today on the web to play a variety of different types -of content. It is often used to play music, podcasts and radio content. At other -times web media is used to provide background music, sound effects, notification -sounds and to render WebRTC media stream content. - -When playing media on the web, developers are currently forced to adopt a single -default platform modality for playing all media content. On the other hand, -native applications can access much richer media integration options with an -underlying platform. On mobile devices, native application developers can -request many different forms of media integration with the platform to obtain -access to headphone buttons, lock screens and notification areas as needed. On -desktop devices, native applications have access to keyboard media key events. -Native application developers can specify the conditions in which media content -should pause or duck on audio interruptions (i.e. pause or lower the volume for -the duration of an interruption), continue playing out when application focus is -lost or the device screen is switched off and interface with internal and -external remote controllers. - -This specification provides these platform media integration features for web -media. By allowing web developers to express the intended usage of their media -content, user agents can supply the most suitable platform-level interactions -for that content and enforce logical interoperation behavior on the current -platform between any number of different sources of media. - -This specification describes the mechanism that allows web developers to specify -the most appropriate kind for their media content and for user agents to then -use these supplied hints to enforce how different sources of web media should -interact with each other, other native media content and the underlying -platform. +Media is used extensively today, and the Web is one of the primary means of +consuming media content. Many platforms can display media metadata, such as +title, artist, album and album art on various UI elements such as notification, +media control center, device lockscreen and wearable devices. This specification +aims to enable web pages to specify the media metadata to be displayed in +platform UI, which helps in improving the user experience.
-[Constructor(optional MediaSessionKind kind = "content")] -interface MediaSession { - readonly attribute MediaSessionKind kind; - attribute MediaMetadata? metadata; - - Promise<void> activate(); - Promise<void> deactivate(); +[Exposed=(Window)] +partial interface Navigator { + readonly attribute MediaSession mediaSession; }; -enum MediaSessionKind { - "content", - "transient", - "transient-solo", - "ambient" +interface MediaSession { + attribute MediaMetadata? metadata; };+The
mediaSession
attribute is
+to retrive an instance of the {{MediaSession}} interface. The attribute MUST
+return the {{MediaSession}} instance associated with the {{Navigator}} object.
+
{{MediaSession}} objects are simply known as media
sessions.
@@ -250,19 +224,6 @@ A media session has metadata,
which is either a {{MediaMetadata}} object or null.
session = new MediaSession([kind])
- session . {{MediaSession/kind}}
- session . {{MediaSession/metadata}}
session . {{MediaSession/activate()}}
- active
.
-
- Throws a {{NotAllowedError}} exception if the request was denied by the user
- agent or the platform.
- session . {{MediaSession/deactivate()}}
- idle
.
- MediaSession(kind)
-constructor, when invoked, must return a new media session whose
-kind is kind, and state is idle
.
-
-The kind
-attribute must return the media session's kind.
-
The metadata
attribute, on
getting, must return the media session's metadata.
-The activate()
method, when
-invoked, must run these steps:
-
-deactivate()
method, when
-invoked, must run these steps:
-
-idle
- active
- interrupted
- content
", "transient
",
-"transient-solo
" and "ambient
".
-
-Kind | -Behavior | -Examples | -
---|---|---|
- "content "
- |
-
-
|
- - Music, podcasts, radio streams. - | -
- "transient "
- |
-
-
|
- - Notification sounds. Spoken driving directions where playback of music - in the background is acceptable. - | -
- "transient-solo "
- |
-
-
|
- - Playback of driving directions. Other spoken notifications. - | -
- "ambient "
- |
-
-
|
- - UI sounds. In-game sound effects and background music. - | -
- When an audio-producing object is ducked any reduction - in volume applied by the user agent is not intended to be observable to web - pages. -
- -active
, then return success.
- content
"
- transient
" or "transient-solo
"
- transient
" or
- "transient-solo
"-based
- media sessions.
- ambient
"
-
- The user agent should not provide user access to any hardware or
- software media keys and not display any ongoing media interface in the
- underlying platform's notifications area or show any ongoing media
- interface in the underlying platform's lock screen area for
- "ambient
"-based media sessions.
-
active
, then return
- success.
- active
media
-session may be interrupted at any time. This typically occurs when another
-application or another media session requests and is granted a level of
-platform media focus that affects the media session based on its
-kind.
-
-Interruptions can be both transient or permanent. A transient interruption means
-we can either choose to duck our media content and continue playing it
-out at a reduced volume for the duration of the interruption; or pause
-our media content for the duration of the interruption and, then, resume
-playback when that interruption ends. A permanent interruption means we must pause our media content indefinitely.
-
-When a start-of-interruption notification event is received from the platform,
-then the user agent must run the
-media session interruption algorithm against all known media
-sessions, passing in each media session as media session.
-
-The media session interruption algorithm takes one argument,
-media session, and consists of the following steps.
-
-active
, then terminate
- these steps.
- content
"
- content
" then
- indefinitely pause all of media session's
- audio-producing participants and set media
- session's state to idle
.
-
- - This implies that the next time the media session is - activated, that we will re-request media focus according to - the steps defined in that algorithm. -
-transient
"
- content
", then terminate these steps.
- interrupted
.
-
- - This implies that the next time the media session continuation - algorithm is run for media session that we will - re-activate this media session according to the steps - defined in that algorithm. -
-transient-solo
"
- content
", "transient
" or
- "transient-solo
", then terminate these steps.
- interrupted
.
-
- - This implies that the next time the media session continuation - algorithm is run for media session that we will - re-activate this media session according to the steps - defined in that algorithm. -
-- -When an end-of-interruption notification event is received from the platform, -then the user agent must run the media session continuation algorithm -against all known media sessions, passing in each media session as -media session. - -The media session continuation algorithm takes one argument, -media session, and consists of the following steps. - -
interrupted
, then
- terminate these steps.
- transient
"
- content
", then terminate these steps.
- active
.
- transient-solo
"
- content
", "transient
", or
- "transient-solo
", then terminate these steps.
- active
.
- ambient
" run the following substeps:
-
- active
, then run
- the following substeps:
-
- interrupted
.
- interrupted
,
- then run the following substeps:
-
- active
.
- idle
, then terminate these
- steps.
- - If the algorithm reaches this step then media session can not - have any remaining audio-producing participants. -
-idle
.
-
- - This implies that the next time the media session is - activated, that we will re-request media focus according to the - steps defined in that algorithm. -
--[Constructor(MediaMetadataInit init)] +[Constructor(optional MediaMetadataInit init)] interface MediaMetadata { readonly attribute DOMString title; readonly attribute DOMString artist; @@ -1195,54 +308,11 @@ attribute must return the {{MediaMetadata}} objects's artwork images, as a FrozenArray of {{MediaImage}}s. The artwork attribute can be empty. -When a user agent wants to display the {{MediaSession}}'s artwork as specified -in it's metadata, it is recommended to run the following fetch -steps: - -- -
- -If no artwork images are fetched in the fetch steps, the user agent may -have fallback behavior such as displaying an default image as artwork. -- - If metadata's
-artwork
is empty, then terminate these - steps. -- - If the platform supports displaying media artwork, select a prefered - artwork image - from metadata's
-artwork
. -- - Fetch prefered artwork image's - {{MediaImage/src}}. - - Then, in parallel: - -
--
-- - Wait for the response. -
-- - If the response's internal response's - type is default, attempt to decode the - resource as image. -
-- - If the image format is supported, use the image as the artwork for - display. Otherwise the fetch steps fail and terminate. -
-The {{MediaImage}} interface
-[Constructor(MediaImageInit init)] +[Constructor(optional MediaImageInit init)] interface MediaImage { readonly attribute USVString src; readonly attribute DOMString sizes; @@ -1318,205 +388,114 @@ The type attribute must return 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. -Extensions to the -{{HTMLMediaElement}} interface
+Processing model
--partial interface HTMLMediaElement { - attribute MediaSession? session; -}; -+As there is a {{Window}} object per browsing context, the top-level +browsing context and each nested browsing context will have an +associated {{MediaSession}} object. For each tab, the user agent MUST select the +{{MediaSession}} object of the top-level browsing context to represent +the tab. The selected {{MediaSession}} object is called tab-level active media session. -
media . {{HTMLMediaElement/session}}
[ =
- session
]
- session
attribute on a media element, on
-getting, must return the element's current media session, if any, or null
-otherwise. On setting, the user agent must run the following steps:
-
-+ It is still an open question whether an {{MediaSession}} object is allowed to + become the tab-level active media session. See the issue on GitHub. +
- +When the user agent has multiple tabs, the user agent MUST select the most +meaningful audio-producing tab and present the tab-level active media +session to the platform, which MAY be displayed in the platform UI depending +on platform conventions. The most meaningful audio-producing tab is +the tab which is producing the most meaningful audio to the user. The user agent +SHOULD select the most meaningful audio-producing tab based on platform +conventions and the preferred user experience. The most meaningful +audio-producing tab can be null. -When the {{play()}} method on a media element is invoked from script – -or a media element is otherwise played from the web page (e.g. via its -{{controls}}) – and that media element's {{paused}} attribute is true -and its {{HTMLMediaElement/readyState}} attribute has the value -{{HAVE_FUTURE_DATA}} or {{HAVE_ENOUGH_DATA}} then the user agent must run the -following steps, passing in media element as media element: +Whenever the most meaningful audio-producing tab changes or settingmetadata
of the most meaningful
+audio-producing tab, the user agent MUST run the update metadata
+algorithm, the steps are as follows:
metadata
for the
+ tab-level active media session of the most meaningful
+ audio-producing tab is null, unset the media metadata presented to the
+ platform, and terminate these steps.
metadata
for the
+ tab-level active media session of the most meaningful
+ audio-producing tab.
artwork
of the tab-level active
+ media session of the most meaningful audio-producing tab is
+ empty, then terminate these steps.
artwork
of the tab-level active
+ media session of the most meaningful audio-producing tab.
-partial interface AudioContext { - attribute MediaSession? session; -}; -- -
context . {{AudioContext/session}}
[ =
- session
]
- session
-attribute on an {{AudioContext}} object, on getting, must return the object's
-current media session, if any, or null otherwise. On setting, the user
-agent must run the following steps:
+ Then, in parallel:
-content
" can be appropriate.
+- var audio = document.createElement("audio"); - audio.src = "podcast.mp3"; - audio.session = new MediaSession(); // "content" is the default kind - audio.play(); -- - If metadata is available, providing it will allow for a richer user interface: - -
- audio.session.metadata = new MediaMetadata({ + window.navigator.mediaSession.metadata = new MediaMetadata({ title: "Episode Title", artist: "Podcast Host", album: "Podcast Title", @@ -1530,7 +509,7 @@ When the user agent is to resume a web audio object for a given for different screens:- audio.session.metadata = new MediaMetadata({ + window.navigator.mediaSession.metadata = new MediaMetadata({ title: "Episode Title", artist: "Podcast Host", album: "Podcast Title", @@ -1554,7 +533,7 @@ When the user agent is to resume a web audio object for a given
function updateMetadata(event) { - sharedSession.metadata = new MediaMetadata({ + window.navigator.mediaSession.metadata = new MediaMetadata({ title: event.target == audio1 ? "Chapter 1" : "Chapter 2", artist: "An Author", album: "A Book", @@ -1592,21 +568,6 @@ When the user agent is to resume a web audio object for a given
ambient
" can be appropriate. Because {{AudioContext}}
- objects are created in the "{{running}}" state, it's necessary to suspend
- before setting the session.
-
- - var context = new AudioContext(); - context.suspend().then(function() { - context.session = new MediaSession("ambient"); - context.resume(); - }); --