| Index: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
|
| diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
|
| index 7079ba7e9dfd636e082a54d1122e4ceb27400671..346840853ffe9f6fbadf354bda4b13c442ac276f 100644
|
| --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
|
| +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
|
| @@ -35,6 +35,7 @@
|
| #include "core/dom/Attribute.h"
|
| #include "core/dom/DOMException.h"
|
| #include "core/dom/ElementTraversal.h"
|
| +#include "core/dom/ElementVisibilityObserver.h"
|
| #include "core/dom/Fullscreen.h"
|
| #include "core/dom/shadow/ShadowRoot.h"
|
| #include "core/events/Event.h"
|
| @@ -354,7 +355,6 @@ private:
|
| Member<HTMLMediaElement> m_element;
|
| };
|
|
|
| -
|
| void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric)
|
| {
|
| DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaElement.Autoplay", NumberOfAutoplayMetrics));
|
| @@ -450,6 +450,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
|
| , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this))
|
| , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.get()))
|
| , m_remotePlaybackClient(nullptr)
|
| + , m_autoplayVisibilityObserver(nullptr)
|
| {
|
| ThreadState::current()->registerPreFinalizer(this);
|
|
|
| @@ -1641,16 +1642,22 @@ void HTMLMediaElement::setReadyState(ReadyState state)
|
| // Check for autoplay, and record metrics about it if needed.
|
| if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) {
|
| recordAutoplaySourceMetric(AutoplaySourceAttribute);
|
| +
|
| // If the autoplay experiment says that it's okay to play now,
|
| // then don't require a user gesture.
|
| m_autoplayHelper->becameReadyToPlay();
|
|
|
| if (!isGestureNeededForPlayback()) {
|
| - m_paused = false;
|
| - invalidateCachedTime();
|
| - scheduleEvent(EventTypeNames::play);
|
| - scheduleNotifyPlaying();
|
| - m_autoplaying = false;
|
| + if (muted() && RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) {
|
| + m_autoplayVisibilityObserver = new ElementVisibilityObserver(this, WTF::bind<bool>(&HTMLMediaElement::onVisibilityChangedForAutoplay, this));
|
| + m_autoplayVisibilityObserver->start();
|
| + } else {
|
| + m_paused = false;
|
| + invalidateCachedTime();
|
| + scheduleEvent(EventTypeNames::play);
|
| + scheduleNotifyPlaying();
|
| + m_autoplaying = false;
|
| + }
|
| }
|
| }
|
|
|
| @@ -2122,6 +2129,12 @@ void HTMLMediaElement::playInternal()
|
| {
|
| DVLOG(MEDIA_LOG_LEVEL) << "playInternal(" << (void*)this << ")";
|
|
|
| + // Playing is about to start from script, no need to wait for visibility.
|
| + if (m_autoplayVisibilityObserver) {
|
| + m_autoplayVisibilityObserver->stop();
|
| + m_autoplayVisibilityObserver = nullptr;
|
| + }
|
| +
|
| // Always return the buffering strategy to normal when not paused,
|
| // regardless of the cause. (In contrast with aggressive buffering which is
|
| // only enabled by pause(), not pauseInternal().)
|
| @@ -3642,6 +3655,7 @@ DEFINE_TRACE(HTMLMediaElement)
|
| visitor->trace(m_autoplayHelperClient);
|
| visitor->trace(m_autoplayHelper);
|
| visitor->trace(m_srcObject);
|
| + visitor->trace(m_autoplayVisibilityObserver);
|
| visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::clearWeakMembers>(this);
|
| Supplementable<HTMLMediaElement>::trace(visitor);
|
| HTMLElement::trace(visitor);
|
| @@ -3859,6 +3873,17 @@ void HTMLMediaElement::recordAutoplaySourceMetric(int source)
|
| }
|
| }
|
|
|
| +void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible)
|
| +{
|
| + if (!isVisible)
|
| + return;
|
| +
|
| + playInternal();
|
| +
|
| + // The observation should have been stopped by the call to playInternal
|
| + DCHECK(!m_autoplayVisibilityObserver);
|
| +}
|
| +
|
| void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
|
| {
|
| if (!ThreadHeap::isHeapObjectAlive(m_audioSourceNode)) {
|
|
|