原文: https://developers.google.com/web/updates/2017/02/media-session
作者:François Beaufort (Taylor is a PM on the Chrome Team, focusing on Web Components and Polymer.)
With the brand new Media Session API, you can now customize media notifications by providing metadata for the media your web app is playing. It also allows you to handle media related events such as seeking or track changing which may come from notifications or media keys. Excited? Try out the official Media Session sample.
Chrome 57将对Media Session API提供支持。Chrome 57的beta版本将于2017年2月发布,而稳定版本将于2017年3月发布。
照片由Michael Alø-Nielsen提供
1. 给我所想
You already know about the Media Session API and are simply coming back to copy and paste with no shame some boilerplate code? So here it is.
你或许已经听说过Media Session API,但也许只是来回复制和粘贴一些简单的样板代码,就像下面一样。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23if ('mediaSession' in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'Never Gonna Give You Up',
artist: 'Rick Astley',
album: 'Whenever You Need Somebody',
artwork: [
{ src: 'https://dummyimage.com/96x96', sizes: '96x96', type: 'image/png' },
{ src: 'https://dummyimage.com/128x128', sizes: '128x128', type: 'image/png' },
{ src: 'https://dummyimage.com/192x192', sizes: '192x192', type: 'image/png' },
{ src: 'https://dummyimage.com/256x256', sizes: '256x256', type: 'image/png' },
{ src: 'https://dummyimage.com/384x384', sizes: '384x384', type: 'image/png' },
{ src: 'https://dummyimage.com/512x512', sizes: '512x512', type: 'image/png' },
]
});
navigator.mediaSession.setActionHandler('play', function() {});
navigator.mediaSession.setActionHandler('pause', function() {});
navigator.mediaSession.setActionHandler('seekbackward', function() {});
navigator.mediaSession.setActionHandler('seekforward', function() {});
navigator.mediaSession.setActionHandler('previoustrack', function() {});
navigator.mediaSession.setActionHandler('nexttrack', function() {});
}
2. 看看代码
2.1 开始播放 🎷
在你的网页中添加audio标签和多个媒体资源,浏览器会从中选择最佳资源。
1 | <audio controls> |
注意: 我也可以用
As you may know, autoplay is disabled for audio elements on Chrome for Android which means we have to use the play() method of the audio element. This method must be triggered by a user gesture such as a touch or a mouse click. That means listening to pointerup, click, and touchend events. In other words, the user must click a button before your web app can actually make noise.
1 | playButton.addEventListener('pointerup', function(event) { |
Note: If the
If you don’t want to play audio right after the first interaction, I recommend you use the load() method of the audio element. This is one way for the browser to keep track of whether the user interacted with the element. Note that it may also help smooth the playback because the content will already be loaded.
1 | let audio = document.querySelector('audio'); |
2.2 定制化通知
When your web app is playing audio, you can already see a media notification sitting in the notification tray. On Android, Chrome does its best to show appropriate information by using the document’s title and the largest icon image it can find.
Without media session
With media session
2.2.1 Set metadata
Let’s see how to customize this media notification by setting some media session metadata such as the title, artist, album name, and artwork with the Media Session API.
1 | // When audio starts playing... |
Once playback is done, you don’t have to “release” the media session as the notification will automatically disappear. Keep in mind that current navigator.mediaSession.metadata will be used when any playback starts. This is why you need to update it to make sure you’re always showing relevant information in the media notification.
2.2.2 Previous track / next track
If your web app provides a playlist, you may want to allow the user to navigate through your playlist directly from the media notification with some “Previous Track” and “Next Track” icons.
1 | let audio = document.createElement('audio'); |
Note that media action handlers will persist. This is very similar to the event listener pattern except that handling an event means that the browser stops doing any default behaviour and uses this as a signal that your web app supports the media action. Hence, media action controls won’t be shown unless you set the proper action handler.
By the way, unsetting a media action handler is as easy as assigning it to null.
2.2.3 Seek backward / seek forward
The Media Session API allows you to show “Seek Backward” and “Seek Forward” media notification icons if you want to control the amount of time skipped.
1 | let skipTime = 10; // Time to skip in seconds |
2.2.4 Play / pause
The “Play/Pause” icon is always shown in the media notification and the related events are handled automatically by the browser. If for some reason the default behaviour doesn’t work out, you can still handle “Play” and “Pause” media events.
1 | navigator.mediaSession.setActionHandler('play', function() { |
3. Notifications everywhere
The cool thing about the Media Session API is that the notification tray is not the only place where media metadata and controls are visible. The media notification is synced automagically to any paired wearable device. And it also shows up on lock screens.
Lock Screen - Photo by Michael Alø-Nielsen / CC BY 2.0
Wear Notification
4. Make it play nice offline
I know what you’re thinking now… service worker to the rescue!
True but first and foremost, you want to make sure all items in this checklist are checked:
- All media and artwork files are served with the appropriate Cache-Control HTTP header. This will allow the browser to cache and reuse previously fetched resources. See the Caching checklist.
- Make sure all media and artwork files are served with the Allow-Control-Allow-Origin: * HTTP header. This will allow third-party web apps to fetch and consume HTTP responses from your web server.
4.1 The service worker caching strategy
Regarding media files, I recommend a simple “Cache, falling back to network” strategy as illustrated by Jake Archibald.
For artwork though, I’d be a little bit more specific and choose the approach below:
- If artwork is already in the cache, serve it from the cache
- Else fetch artwork from the network
- If fetch is successful, add network artwork to the cache and serve it
- Else serve the fallback artwork from the cache
That way, media notifications will always have a nice artwork icon even when browser can’t fetch them. Here’s how you could implement this:
1 | const FALLBACK_ARTWORK_URL = 'fallbackArtwork.png'; |
Caution: If you want your service worker to be able to intercept artwork network requests on the very first page load, you may want to call clients.claim() within your service worker once it’s activated.
4.2 Let user control cache
As the user consumes content from your web app, media and artwork files may take a lot of space on their device. It is your responsibility to show how much cache is used and give users the ability to clear it. Thankfully for us, doing so is pretty easy with the Cache API.
1 | // Here's how I'd compute how much cache is used by artwork files... |
5. Implementation notes
- Chrome for Android requests “full” audio focus to show media notifications only when the media file duration is at least 5 seconds.
- Notification artwork support blob URLs and data URLs.
- If no artwork is defined and there is an icon image at a desirable size, media notifications will use it.
- Notification artwork size in Chrome for Android is 512x512. For low-end devices, it is 256x256.
- Dismiss media notifications with audio.src = ‘’.
- As the Web Audio API doesn’t request Android Audio Focus for historical reasons, the only way to make it work with the Media Session API is to hook up an
6. Support
At the time of writing, Chrome for Android is the only platform that supports the Media Session API. More up-to-date information on browser implementation status can be found on Chrome Platform Status.
7. Samples & demos
Check out our official Chrome Media Session sample featuring Jan Morgenstern’s work.
视频地址:https://storage.googleapis.com/media-session/screenrecord.mp4
8. Resources
Media Session Spec: https://wicg.github.io/mediasession
Spec Issues: https://github.com/WICG/mediasession/issues
Chrome Bugs: https://crbug.com/?q=component:Internals>Media>Session