diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 734a85148ba7..d6afeaba4c82 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -1876,7 +1876,8 @@ void HTMLMediaElement::SetVolumeInternal() } } - UpdateAudioChannelPlayingState(); + NotifyAudioPlaybackChanged( + AudioChannelService::AudibleChangedReasons::eVolumeChanged); } NS_IMETHODIMP HTMLMediaElement::SetMuted(bool aMuted) @@ -2281,7 +2282,8 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed& aNo mHasUserInteraction(false), mFirstFrameLoaded(false), mDefaultPlaybackStartPosition(0.0), - mIsAudioTrackAudible(false) + mIsAudioTrackAudible(false), + mAudible(IsAudible()) { mAudioChannel = AudioChannelService::GetDefaultAudioChannel(); @@ -4969,8 +4971,8 @@ HTMLMediaElement::IsPlayingThroughTheAudioChannel() const return true; } - // Are we paused or muted - if (mPaused || Muted()) { + // Are we paused + if (mPaused) { return false; } @@ -4984,11 +4986,6 @@ HTMLMediaElement::IsPlayingThroughTheAudioChannel() const return false; } - // The volume should not be ~0 - if (std::fabs(Volume()) <= 1e-7) { - return false; - } - // We should consider any bfcached page or inactive document as non-playing. if (!IsActive()) { return false; @@ -5053,7 +5050,7 @@ HTMLMediaElement::NotifyAudioChannelAgent(bool aPlaying) // any sound. AudioPlaybackConfig config; nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(&config, - mIsAudioTrackAudible); + IsAudible()); if (NS_WARN_IF(NS_FAILED(rv))) { return; } @@ -5114,6 +5111,9 @@ HTMLMediaElement::WindowSuspendChanged(SuspendTypes aSuspend) "Error : unknown suspended type!\n", this)); } + NotifyAudioPlaybackChanged( + AudioChannelService::AudibleChangedReasons::ePauseStateChanged); + return NS_OK; } @@ -5609,16 +5609,45 @@ HTMLMediaElement::SetAudibleState(bool aAudible) { if (mIsAudioTrackAudible != aAudible) { mIsAudioTrackAudible = aAudible; - NotifyAudioPlaybackChanged(); + NotifyAudioPlaybackChanged( + AudioChannelService::AudibleChangedReasons::eDataAudibleChanged); } } void -HTMLMediaElement::NotifyAudioPlaybackChanged() +HTMLMediaElement::NotifyAudioPlaybackChanged(AudibleChangedReasons aReason) { - if (mAudioChannelAgent) { - mAudioChannelAgent->NotifyStartedAudible(mIsAudioTrackAudible); + if (!mAudioChannelAgent) { + return; } + + if (mAudible == IsAudible()) { + return; + } + + mAudible = IsAudible(); + mAudioChannelAgent->NotifyStartedAudible(mAudible, aReason); +} + +bool +HTMLMediaElement::IsAudible() const +{ + // Muted or the volume should not be ~0 + if (Muted() || (std::fabs(Volume()) <= 1e-7)) { + return false; + } + + // No sound can be heard during suspending. + if (IsSuspendedByAudioChannel()) { + return false; + } + + // Silent audio track. + if (!mIsAudioTrackAudible) { + return false; + } + + return true; } } // namespace dom diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index f514419d67cb..01d8decf9350 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -38,6 +38,7 @@ typedef uint16_t nsMediaNetworkState; typedef uint16_t nsMediaReadyState; typedef uint32_t SuspendTypes; +typedef uint32_t AudibleChangedReasons; namespace mozilla { class DecoderDoctorDiagnostics; @@ -453,7 +454,7 @@ public: virtual void SetAudibleState(bool aAudible) final override; // Notify agent when the MediaElement changes its audible state. - void NotifyAudioPlaybackChanged(); + void NotifyAudioPlaybackChanged(AudibleChangedReasons aReason); // XPCOM GetPreload() is OK void SetPreload(const nsAString& aValue, ErrorResult& aRv) @@ -1175,6 +1176,8 @@ protected: bool IsAllowedToPlay(); + bool IsAudible() const; + class nsAsyncEventRunner; using nsGenericHTMLElement::DispatchEvent; // For nsAsyncEventRunner. @@ -1606,8 +1609,11 @@ private: // be seeked even before the media is loaded. double mDefaultPlaybackStartPosition; - // True if the audio track is producing audible sound. + // True if the audio track is not silent. bool mIsAudioTrackAudible; + + // True if media element is audible for users. + bool mAudible; }; } // namespace dom