Expose to web content whether autoplay is blocked

RESOLVED FIXED in Firefox 63

Status

()

enhancement
P2
normal
RESOLVED FIXED
10 months ago
9 months ago

People

(Reporter: cpearce, Assigned: cpearce)

Tracking

(Depends on 1 bug, Blocks 1 bug, {dev-doc-complete})

unspecified
mozilla63
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(firefox63 fixed)

Details

Attachments

(1 attachment)

Various web authors have expressed desire to know in advance whether autoplay will work.

They want this in order to avoid paying the price for downloading media that won't play. Or they want to take other action such as showing a poster image instead.

This is of particular interest to Firefox (more so than other browser vendors I'd wager), as we're planning on showing a prompt to ask the user whether they would like a site to play. If sites want to determine whether they can autoplay but avoid the prompt showing, they won't be able to just call play() in Firefox and see whether it works, as that would likely show the prompt if the user doesn't already have a stored permission.

We've been working out a spec here:
https://github.com/whatwg/html/issues/3617#issuecomment-398613484

What I want to implement is:

partial interface HTMLMediaElement {
  readonly attribute boolean allowedToPlay;
};

HTMLMediaElement.allowedToPlay is true if calls to HTMLMediaElement.play() on this HTMLMediaElement would not be blocked by autoplay blocking policies. That is, if the promise returned by calling HTMLMediaElement.play() would not be rejected with NotAllowedErr.

HTMLMediaElement.allowedToPlay is a function of the known attributes/characteristics of the HTMLMediaElement and environment. Unknown characteristics are assumed to be the worst case. For example, if prompting for permission is enabled, and no permission value is stored for the origin trying to autoplay, the implementation behaves as if the user would not grant permission.

HTMLMediaElement.allowedToPlay does not represent whether the play would otherwise succeed, only whether the play would be blocked, i.e. it doesn't report whether the resource being loaded is playable by the browser's playback engine.

HTMLMediaElement.allowedToPlay works on media elements which have no resource; in such cases it would just take into account the current state of the media element's attributes, such as its muted attribute.
Comment hidden (mozreview-request)

Comment 2

10 months ago
mozreview-review
Comment on attachment 8994730 [details]
Bug 1478208 - Implement HTMLMediaElement.allowedToPlay.

https://reviewboard.mozilla.org/r/259250/#review266514

LGTM, thank you!
Attachment #8994730 - Flags: review?(alwu) → review+

Comment 3

10 months ago
mozreview-review
Comment on attachment 8994730 [details]
Bug 1478208 - Implement HTMLMediaElement.allowedToPlay.

https://reviewboard.mozilla.org/r/259250/#review266542

r=me with the issues below addressed.

::: commit-message-dd386:16
(Diff revision 1)
> +prompt to ask the user whether they would like a site to play. If sites want to
> +determine whether they can autoplay but avoid the prompt showing, they won't be
> +able to just call play() in Firefox and see whether it works, as that would
> +likely show the prompt if the user doesn't already have a stored permission.
> +
> +We've been working out a spec here:

Could you send an intent mail, please?

::: browser/app/profile/firefox.js:1459
(Diff revision 1)
>  pref("media.autoplay.ask-permission", true);
>  // Set Firefox to block autoplay, asking for permission by default.
>  pref("media.autoplay.default", 2); // 0=Allowed, 1=Blocked, 2=Prompt
> +// HTMLMediaElement.allowedToPlay is visible along with block autoplay
> +// v2 being enabled.
> +pref("media.allowed-to-play.enabled", true);

The else branch should set a value too, no?

::: dom/html/HTMLMediaElement.cpp:2528
(Diff revision 1)
>  }
>  
> +bool
> +HTMLMediaElement::AllowedToPlay() const
> +{
> +  return AutoplayPolicy::IsAllowedToPlay(*this) == nsIAutoplay::ALLOWED;

Is this guaranteed to be a value we can evaluate sync?  As in, we don't need a promise here?

::: dom/webidl/HTMLMediaElement.webidl:228
(Diff revision 1)
> +/*
> + * API that exposes whether a call to HTMLMediaElement.play() would be
> + * blocked by autoplay policies; whether the promise returned by play()
> + * would be rejected with NotAllowedError.
> + */
> +partial interface HTMLMediaElement {

Please link to the spec draft in a comment before the partial interface and in the comment near the top of the file.  The idea is that for any spec-related IDL it should be easy to find the relevent spec from our .webidl file.

::: mobile/android/app/mobile.js:586
(Diff revision 1)
>  pref("media.autoplay.ask-permission", false);
>  // Set Fennec to block autoplay by default.
>  pref("media.autoplay.default", 1); // 0=Allowed, 1=Blocked, 2=Prompt
> +// HTMLMediaElement.allowedToPlay is visible along with block autoplay
> +// v2 being enabled.
> +pref("media.allowed-to-play.enabled", true);

#else branch needs to have the pref too.

::: modules/libpref/init/all.js:586
(Diff revision 1)
>  pref("media.autoplay.enabled.user-gestures-needed", false);
>  #endif
>  
> +// HTMLMediaElement.allowedToPlay should be exposed to web content when
> +// block autoplay rides the trains to release.
> +pref("media.allowed-to-play.enabled", false);

I'm not a fan of having the default false here but the overriding true bits in the other pref files.  Why not just put it all here (with the ifdef)?
Attachment #8994730 - Flags: review?(bzbarsky) → review+
Keywords: dev-doc-needed
Assignee

Comment 4

10 months ago
(In reply to Boris Zbarsky [:bz] (no decent commit message means r-) from comment #3)
> Comment on attachment 8994730 [details]
> Bug 1478208 - Implement HTMLMediaElement.allowedToPlay.
> 
> https://reviewboard.mozilla.org/r/259250/#review266542
> 
> r=me with the issues below addressed.
> 
> ::: commit-message-dd386:16
> (Diff revision 1)
> > +prompt to ask the user whether they would like a site to play. If sites want to
> > +determine whether they can autoplay but avoid the prompt showing, they won't be
> > +able to just call play() in Firefox and see whether it works, as that would
> > +likely show the prompt if the user doesn't already have a stored permission.
> > +
> > +We've been working out a spec here:
> 
> Could you send an intent mail, please?

Sure: https://groups.google.com/forum/#!topic/mozilla.dev.platform/BPZHwDp_Ciw


> ::: dom/html/HTMLMediaElement.cpp:2528
> (Diff revision 1)
> >  }
> >  
> > +bool
> > +HTMLMediaElement::AllowedToPlay() const
> > +{
> > +  return AutoplayPolicy::IsAllowedToPlay(*this) == nsIAutoplay::ALLOWED;
> 
> Is this guaranteed to be a value we can evaluate sync?  As in, we don't need
> a promise here?

Based on the current way we do permissions, yes.


> 
> ::: dom/webidl/HTMLMediaElement.webidl:228
> (Diff revision 1)
> > +/*
> > + * API that exposes whether a call to HTMLMediaElement.play() would be
> > + * blocked by autoplay policies; whether the promise returned by play()
> > + * would be rejected with NotAllowedError.
> > + */
> > +partial interface HTMLMediaElement {
> 
> Please link to the spec draft in a comment before the partial interface and
> in the comment near the top of the file.  The idea is that for any
> spec-related IDL it should be easy to find the relevent spec from our
> .webidl file.

Do you mind if I do this in a follow up bug once the spec PR is merged?
Flags: needinfo?(bzbarsky)
That's fine, as long as the link ends up in the IDL in the end.
Flags: needinfo?(bzbarsky)
Assignee

Comment 6

10 months ago
mozreview-review
Comment on attachment 8994730 [details]
Bug 1478208 - Implement HTMLMediaElement.allowedToPlay.

https://reviewboard.mozilla.org/r/259250/#review267932

::: modules/libpref/init/all.js:586
(Diff revision 1)
>  pref("media.autoplay.enabled.user-gestures-needed", false);
>  #endif
>  
> +// HTMLMediaElement.allowedToPlay should be exposed to web content when
> +// block autoplay rides the trains to release.
> +pref("media.allowed-to-play.enabled", false);

The block autoplay prefs are off by default and turned on in a per-product basis. The idea being that products that opt-into blocking autoplay can do so with their prefs.

Admitedly, that doesn't make as much sense for allowedToPlay, as its reasonable for that to be present in products that haven't opted into block autoplay. So I'll move the media.allowed-to-play.enabled pref initialization into here.
Assignee

Updated

10 months ago
Depends on: 1480302
Assignee

Comment 7

10 months ago
Filed bug 1480302 to follow up with updating the IDL.
Comment hidden (mozreview-request)

Comment 9

10 months ago
Pushed by cpearce@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/f5f55e363d31
Implement HTMLMediaElement.allowedToPlay. r=alwu,bz

Comment 10

10 months ago
bugherder
https://hg.mozilla.org/mozilla-central/rev/f5f55e363d31
Status: NEW → RESOLVED
Last Resolved: 10 months ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla63
This has been added to Experimental features in Firefox:

https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Experimental_features#DOM

It won’t be added to the overall documentation until and unless it starts to ride the trains, or becomes an official part of the specification with at least one browser implementing it in a release build.
Please be sure to put dev-doc-needed on any bug filed in the future about enabling this to escape nightly-only status and/or to outright ride the trains.
You need to log in before you can comment on or make changes to this bug.