See the entire conversation

39 replies and sub-replies as of Dec 20 2020

Looks like the owner of the Project Fugu ticket for SW audio playback has become inactive: bugs.chromium.org/p/chromium/iss… What’s the best practice for me to handle that? Is it irrelevant for now or should I highlight it so eg. the owner can be removed / reassigned?
Let's ask @slightlylate (tech lead) and @fractorious (PM) :)
Oh hai. So, it's a complex picture with many options. Media playback is assumed to be tied to (visible) app lifetime on all modern OSes. We match that today, and allow backgrounded PWAs to project media via MediaSession APIs:
Customize media notifications and playback controls with the Media Session API
Web developers can customize media notifications and respond to media related events such as seeking or track changing with the Media Session API.
web.dev
We keep the media playing reliably (from HTML, yes), even when the app is moved out of focus. SW playback wouldn't change that. Can you say more about the gaps you perceive? I think we're actually in good shape here (on good OSes, which is to say, perhaps not iOS).
Just verified this works as expected from a media PWA (open.spotify.com). Media keeps playing when the PWA is in the background, even when the screen is off, and remote playback contracts (e.g. from headphones) work. What's missing?
The missing part is that it only works for SPA:s as any navigation to a new page will break playback + in a non-installed scenario any external link even breaks SPA playback. When I filed this issue I worked in a newspaper and we didn’t have a SPA.
Same applies if I want to have a podcast functionality at eg my Eleventy site – I then want any link clicks in eg. the episode description to not disrupt the playback
Ok, I see...you want a way to keep media alive across navigations. We don't have a DOM exposed to SWs, but we've heard similar requests for video overlays and such. /cc @hochsays @jaffathecake
Can imagine APIs that will work for this using "regular" <audio> and <video> playback (no MSE); no idea how to make it work for WebAudio. Perhaps making it possible to delegate media to a Worker, then have the Worker survive the navigation and re-attach? /cc @FalkenMatto
I'm pretty worried about making this stuff too special-case-ish (e.g. transparently re-attaching in-flight playback to media elements with the same IDs), as I can't figure out how to make that work in more professional cases (protected media)
If ServiceWorkerGlobalScope can instantiate AudioContexts, would it solve the problem for WebAudio?
We want to be able to kill off SW scopes, so I don't think so. What we really need is a way to be able to isolate a media element and it's associated heap and keep it alive across navigations; hence my suggestion about Dedicated Workers.
E.g. you'd mark a Worker as somehow "detatchable" and send a media element to it (transferrable?) and make it possible to create AudioWorkletGlobalScopes there too. Assuming you could somehow re-attach the transferred media element to a new "facade" element, could work
That way, the SW would see the client object for the worker the whole time; it just wouldn't blink out of existence the way the document it was spawned from would. ...which makes me think the _right_ answer might be SharedWorker?
Thanks for the suggestion! Detaching "things" has been a constant issue for WebAudio in general, so I'll have to think about its implication. In Chrome, AudioContext has a strong tie to the document.
But also it seems like we need to make AudioContext transferrable. That seems like a non-trivial change. That said, definitely an interesting direction.
The primary use case will be supporting seamless media playback, so the appropriate spec domain would be "HTMLMediaElement" first and then Web Audio API. Right?
This is why I'm saying we probably want to construct things inside the heap where they'll live, e.g. a SharedWorker
Could you solve this with portals? On navigation the player page becomes an iframe on whatever pages you navigate to afterwards? That seems to require special handling on every navigation which would be annoying but maybe you could abstract it away somehow.
We get this same question a lot for device APIs. It would be nice to have a standard answer for keeping a part of a page alive as long as the user doesn't close the tab or navigate it cross-origin. A transferrable dedicated worker would work as well.
You see sites like YouTube implementing a mini-player to solve this but to do so they need to be a single-page app so that they never truly navigate. As I understand it part of the appeal of portals is to allow SPA-like smoothness while navigating like a normal web page.
Portals allow you to adopt the previous page as a portal. The problem is if you keep doing that you create a chain of pages to keep alive, and we'll need to start killing them at some point.
Got it. I thought they were a bit more flexible than that. You would need a way to pass an arbitrary set of other portals on navigation which comes back to the general issue of passing resources (workers, sockets, etc.) across navigation.
Fwiw, shared workers already have this concept of staying alive between pages, but no one implements it (sorry if this came up already)
Shared workers work as long as the resource in question can be owned by a worker. My intuition is that when it comes to things that logically reside in the DOM (like video players) using a shared worker would be awkward even if it were possible. Maybe I'm wrong there.
Right, we'd need offscreen canvas but for media
I think video and audio have different requirements here. Audio make sense for a user to play in the background and, given the permission(?), to continue to do so even after a cross-origin navigation. Clicking a link in a podcast description shouldn’t disrupt the podcast
Also, multiple tabs for same PWA should ideally control same audio playback. Someone visiting the Spotify PWA in two tabs should still only control a single playback and similarly of an indie podcast site, makes no sense for such a PWA to have multiple simultaneous playbacks.
An option to lock down a single media source for the domain would be powerful. It could be solved as a side effect of the media-capable worker you've proposed. Or could be just as an attribute of audio/video tags.
Depends if a simple <audio> is enough, or if it needs state like adaptive bitrate media source stuff
And on top of that maybe something like the Audio Focus API might be needed to play nicely with the OS:
WICG/audio-focus
Contribute to WICG/audio-focus development by creating an account on GitHub.
github.com
I don't think it's so binary. Eg, in some cases the video component of a music video is low priority for the user.
Sure, but background playback of it essentially becomes audio playback of a video? Do audio elements currently support playback of the audio track of a video? I’m thinking that maybe a background video could be solved through handling it as audio?
I think that would make sense. I don't know if <audio> can load video today.
It also looks pretty good in stand-alone!
Right. If we were to come up with a way to keep media playback alive across navigations, it might involve SWs, but not 100% sure it would depend on them.
There are quite a few links to the different specs (Web Audio, Media Session, Audio Focus) and related issues in them within my issues + a few links in them to older Twitter discussions, including to when I originally bugged @Lady_Ada_King about this some 3 years ago 🤭
I'd missed the audio-focus explainer before...looks valuable and maybe something we could tie this into. That said, it's Explainer needs to drop the IDL (*cough* @marcosc *cough*) and probably needs to be refactored to move away from constructors.