13
votes

Tracking state of Chrome's Click-to-play feature

How do you detect that a Flash plugin has been temporarily disabled, or, conversely, detect that it has been enabled due to Chrome's "click-to-play" feature?

Background

Chrome's new "click-to-play" feature detects plugins that are not visibly significant and pauses them. Chrome displays a "play" button over the plugin, a user may click the "play" button to activate the plugin. (reference: https://productforums.google.com/forum/#!topic/chrome/xPcpRBzyPcc)

Here's a screenshot of it in action (notice white play buttons): NFL.com Flash plugin disabled by default

You can see in this screen shot that it has paused a video-player (right column). That video player has HTML5-based controls overlaying a Flash-based video player. So, there's no way for a user to click the play-button as the entire SWF is purposefully covered by HTML5-based play/pause controls.

What I need is to detect when the SWF has been paused by the "click-to-play" feature so I can disable the controls and make the SWF interactive.

What I've tried

  1. In JavaScript - All methods exposed via ExternalInterface are still available though the SWF is paused. It actually responds like it's playing and does not return an error.
  2. In JavaScript - Update the size of the embedded <object> to > 700x400px. "Click-to-play" does not pause a SWF of this size. So, I tried using -webkit-transfor: scale(0.5) to use CSS to scale it back to desired size. Chrome calculates the final rendered size and pauses the SWF regardless.
  3. In Flash - stage.frameRate returns correct value (it's not set to 0 to pause the SWF for instance)

In writing up this question I found an answer, decided to post here anyways in case others need help with this issue.

3

3 Answers

3
votes

For the benefit of others who are looking for the rules around Flash blocking stuff,please see them below:

  • The Flash Content and the page are loaded from the same domain.
    Unknown Width and Height of the Flash Object ie when Chrome gets the width and height as 0 or less than 0.
  • The Flash Content is whitelisted by the user in Chrome Settings.
  • The Width and Height of the Flash Object are less than or equal to 5 each, considering the content to be Tiny and essential.
  • The Width and Height of the Flash object are equal or greater than 398x298.
  • The Aspect Ratio of the content is 16:9, (with an allowed deviation of 0.01) AND the width*height area is at least 120K.

At least one of the above criterias need to be met, in order to get the content marked as Essential and not get Auto-Paused. Although, I have seen few deviations and Chrome hasn't made any public announcement on the rules yet.

2
votes

Add an empty Flash file larger than 398x298 at the bottom of your page. I found once you have at least one Flash file above their minimum Chrome will not pause any of your Flash. You cannot hide this extra Flash file with CSS. Optionally use a javascript timeout (3 seconds) to hide the empty Flash file in case it messes with your page layout. I'm using swfObject for embedding.

2
votes

To circumvent the Chrome click-to-play throttling, load your SWF from the same domain and protocol as your site.


You can use the AS3 ThrottleEvent to detect when the SWF has been throttled.

// AS3 code
import flash.events.ThrottleEvent;
import flash.external.ExternalInterface;

stage.addEventListener(ThrottleEvent.THROTTLE, onThrottleEvent);

private function onThrottleEvent(e:ThrottleEvent) {
    ExternalInterface.call("onThrottleEvent", e.state); // call javascript function 
}

You can setup an ExternalInterface call to keep track of this state in JavaScript, in JavaScript manage z-index of your SWF based on if it's throttled or not.

// JS Code
var IS_THROTTLED = false;

window.onThrottleEvent = function (throttleState) {
  IS_THROTTLED = (throttleState === "throttle");
}