2 * Copyright (C) 2007-2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "ActiveDOMObject.h"
31 #include "AutoplayEvent.h"
32 #include "GenericEventQueue.h"
33 #include "GenericTaskQueue.h"
34 #include "HTMLElement.h"
35 #include "HTMLMediaElementEnums.h"
36 #include "MediaCanStartListener.h"
37 #include "MediaControllerInterface.h"
38 #include "MediaElementSession.h"
39 #include "MediaProducer.h"
40 #include "VisibilityChangeClient.h"
41 #include <wtf/Function.h>
42 #include <wtf/WeakPtr.h>
44 #if ENABLE(VIDEO_TRACK)
45 #include "AudioTrack.h"
46 #include "CaptionUserPreferences.h"
47 #include "PODIntervalTree.h"
48 #include "TextTrack.h"
49 #include "TextTrackCue.h"
51 #include "VideoTrack.h"
54 #if USE(AUDIO_SESSION) && PLATFORM(MAC)
55 #include "AudioSession.h"
59 #include <wtf/StringPrintStream.h>
64 class AudioSourceProvider;
66 class AudioTrackPrivate;
69 class DeferredPromise;
72 class HTMLSourceElement;
73 class HTMLTrackElement;
74 class InbandTextTrackPrivate;
75 class MediaController;
77 class MediaControlsHost;
78 class MediaElementAudioSourceNode;
82 class MediaResourceLoader;
87 class ScriptExecutionContext;
91 class VideoPlaybackQuality;
93 class VideoTrackPrivate;
94 class WebKitMediaKeys;
96 template<typename> class DOMPromiseDeferred;
98 #if ENABLE(VIDEO_TRACK)
99 using CueIntervalTree = PODIntervalTree<MediaTime, TextTrackCue*>;
100 using CueInterval = CueIntervalTree::IntervalType;
101 using CueList = Vector<CueInterval>;
104 using MediaProvider = std::optional<Variant<
105 #if ENABLE(MEDIA_STREAM)
108 #if ENABLE(MEDIA_SOURCE)
113 class HTMLMediaElement
115 , public ActiveDOMObject
116 , public MediaControllerInterface
117 , public MediaPlayerSupportsTypeClient
118 , public PlatformMediaSessionClient
119 , private MediaCanStartListener
120 , private MediaPlayerClient
121 , private MediaProducer
122 , private VisibilityChangeClient
123 #if ENABLE(VIDEO_TRACK)
124 , private AudioTrackClient
125 , private TextTrackClient
126 , private VideoTrackClient
128 #if USE(AUDIO_SESSION) && PLATFORM(MAC)
129 , private AudioSession::MutedStateObserver
133 WeakPtr<HTMLMediaElement> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
134 MediaPlayer* player() const { return m_player.get(); }
136 virtual bool isVideo() const { return false; }
137 bool hasVideo() const override { return false; }
138 bool hasAudio() const override;
140 static HashSet<HTMLMediaElement*>& allMediaElements();
142 static HTMLMediaElement* bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose);
144 void rewind(double timeDelta);
145 WEBCORE_EXPORT void returnToRealtime() override;
147 // Eventually overloaded in HTMLVideoElement
148 bool supportsFullscreen(HTMLMediaElementEnums::VideoFullscreenMode) const override { return false; };
150 bool supportsScanning() const override;
152 bool canSaveMediaData() const;
154 bool doesHaveAttribute(const AtomicString&, AtomicString* value = nullptr) const override;
156 WEBCORE_EXPORT PlatformMedia platformMedia() const;
157 PlatformLayer* platformLayer() const;
158 bool isVideoLayerInline();
159 void setPreparedToReturnVideoLayerToInline(bool);
160 void waitForPreparedForInlineThen(WTF::Function<void()>&& completionHandler = [] { });
161 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
162 void setVideoFullscreenLayer(PlatformLayer*, WTF::Function<void()>&& completionHandler = [] { });
163 PlatformLayer* videoFullscreenLayer() const { return m_videoFullscreenLayer.get(); }
164 void setVideoFullscreenFrame(FloatRect);
165 void setVideoFullscreenGravity(MediaPlayerEnums::VideoGravity);
166 MediaPlayerEnums::VideoGravity videoFullscreenGravity() const { return m_videoFullscreenGravity; }
169 using HTMLMediaElementEnums::DelayedActionType;
170 void scheduleDelayedAction(DelayedActionType);
171 void scheduleResolvePendingPlayPromises();
172 void rejectPendingPlayPromises(DOMError&);
173 void resolvePendingPlayPromises();
174 void scheduleNotifyAboutPlaying();
175 void notifyAboutPlaying();
177 MediaPlayerEnums::MovieLoadType movieLoadType() const;
179 bool inActiveDocument() const { return m_inActiveDocument; }
181 const Document* hostingDocument() const override { return &document(); }
185 WEBCORE_EXPORT MediaError* error() const;
187 const URL& currentSrc() const { return m_currentSrc; }
189 const MediaProvider& srcObject() const { return m_mediaProvider; }
190 void setSrcObject(MediaProvider&&);
192 WEBCORE_EXPORT void setCrossOrigin(const AtomicString&);
193 WEBCORE_EXPORT String crossOrigin() const;
196 using HTMLMediaElementEnums::NetworkState;
197 WEBCORE_EXPORT NetworkState networkState() const;
199 WEBCORE_EXPORT String preload() const;
200 WEBCORE_EXPORT void setPreload(const String&);
202 Ref<TimeRanges> buffered() const override;
203 WEBCORE_EXPORT void load();
204 WEBCORE_EXPORT String canPlayType(const String& mimeType) const;
207 using HTMLMediaElementEnums::ReadyState;
208 ReadyState readyState() const override;
209 WEBCORE_EXPORT bool seeking() const;
212 WEBCORE_EXPORT double currentTime() const override;
213 void setCurrentTime(double) override;
214 double currentTimeForBindings() const { return currentTime(); }
215 WEBCORE_EXPORT ExceptionOr<void> setCurrentTimeForBindings(double);
216 WEBCORE_EXPORT double getStartDate() const;
217 WEBCORE_EXPORT double duration() const override;
218 WEBCORE_EXPORT bool paused() const override;
219 double defaultPlaybackRate() const override;
220 void setDefaultPlaybackRate(double) override;
221 WEBCORE_EXPORT double playbackRate() const override;
222 void setPlaybackRate(double) override;
224 // MediaTime versions of playback state
225 MediaTime currentMediaTime() const;
226 void setCurrentTime(const MediaTime&);
227 MediaTime durationMediaTime() const;
228 WEBCORE_EXPORT void fastSeek(const MediaTime&);
230 void updatePlaybackRate();
231 WEBCORE_EXPORT bool webkitPreservesPitch() const;
232 WEBCORE_EXPORT void setWebkitPreservesPitch(bool);
233 Ref<TimeRanges> played() override;
234 Ref<TimeRanges> seekable() const override;
235 double seekableTimeRangesLastModifiedTime() const;
236 double liveUpdateInterval() const;
237 WEBCORE_EXPORT bool ended() const;
238 bool autoplay() const;
239 bool isAutoplaying() const { return m_autoplaying; }
241 void setLoop(bool b);
243 void play(DOMPromiseDeferred<void>&&);
245 WEBCORE_EXPORT void play() override;
246 WEBCORE_EXPORT void pause() override;
247 void setShouldBufferData(bool) override;
248 WEBCORE_EXPORT void fastSeek(double);
249 double minFastReverseRate() const;
250 double maxFastForwardRate() const;
252 void purgeBufferedDataIfPossible();
255 WEBCORE_EXPORT bool webkitHasClosedCaptions() const;
256 WEBCORE_EXPORT bool webkitClosedCaptionsVisible() const;
257 WEBCORE_EXPORT void setWebkitClosedCaptionsVisible(bool);
259 bool elementIsHidden() const override { return m_elementIsHidden; }
261 #if ENABLE(MEDIA_STATISTICS)
263 unsigned webkitAudioDecodedByteCount() const;
264 unsigned webkitVideoDecodedByteCount() const;
267 #if ENABLE(MEDIA_SOURCE)
269 void detachMediaSource();
270 void incrementDroppedFrameCount() { ++m_droppedVideoFrames; }
271 size_t maximumSourceBufferSize(const SourceBuffer&) const;
274 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
275 WebKitMediaKeys* webkitKeys() const { return m_webKitMediaKeys.get(); }
276 void webkitSetMediaKeys(WebKitMediaKeys*);
281 #if ENABLE(ENCRYPTED_MEDIA)
282 MediaKeys* mediaKeys() const;
284 void setMediaKeys(MediaKeys*, Ref<DeferredPromise>&&);
288 WEBCORE_EXPORT bool controls() const;
289 WEBCORE_EXPORT void setControls(bool);
290 WEBCORE_EXPORT double volume() const override;
291 ExceptionOr<void> setVolume(double) override;
292 WEBCORE_EXPORT bool muted() const override;
293 WEBCORE_EXPORT void setMuted(bool) override;
295 WEBCORE_EXPORT void togglePlayState();
296 WEBCORE_EXPORT void beginScrubbing() override;
297 WEBCORE_EXPORT void endScrubbing() override;
299 void beginScanning(ScanDirection) override;
300 void endScanning() override;
301 double nextScanRate();
303 WEBCORE_EXPORT bool canPlay() const override;
305 double percentLoaded() const;
307 bool shouldForceControlsDisplay() const;
309 #if ENABLE(VIDEO_TRACK)
310 ExceptionOr<TextTrack&> addTextTrack(const String& kind, const String& label, const String& language);
312 AudioTrackList& audioTracks();
313 TextTrackList& textTracks();
314 VideoTrackList& videoTracks();
316 CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
318 void addAudioTrack(Ref<AudioTrack>&&);
319 void addTextTrack(Ref<TextTrack>&&);
320 void addVideoTrack(Ref<VideoTrack>&&);
321 void removeAudioTrack(AudioTrack&);
322 void removeTextTrack(TextTrack&, bool scheduleEvent = true);
323 void removeVideoTrack(VideoTrack&);
324 void forgetResourceSpecificTracks();
325 void closeCaptionTracksChanged();
326 void notifyMediaPlayerOfTextTrackChanges();
328 virtual void didAddTextTrack(HTMLTrackElement&);
329 virtual void didRemoveTextTrack(HTMLTrackElement&);
331 void mediaPlayerDidAddAudioTrack(AudioTrackPrivate&) final;
332 void mediaPlayerDidAddTextTrack(InbandTextTrackPrivate&) final;
333 void mediaPlayerDidAddVideoTrack(VideoTrackPrivate&) final;
334 void mediaPlayerDidRemoveAudioTrack(AudioTrackPrivate&) final;
335 void mediaPlayerDidRemoveTextTrack(InbandTextTrackPrivate&) final;
336 void mediaPlayerDidRemoveVideoTrack(VideoTrackPrivate&) final;
338 #if ENABLE(AVF_CAPTIONS)
339 Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources() final;
343 void configureTextTrackGroupForLanguage(const TrackGroup&) const;
344 void configureTextTracks();
345 void configureTextTrackGroup(const TrackGroup&);
347 void setSelectedTextTrack(TextTrack*);
349 bool textTracksAreReady() const;
350 using HTMLMediaElementEnums::TextTrackVisibilityCheckType;
351 void configureTextTrackDisplay(TextTrackVisibilityCheckType checkType = CheckTextTrackVisibility);
352 void updateTextTrackDisplay();
355 void audioTrackEnabledChanged(AudioTrack&) final;
357 void textTrackReadyStateChanged(TextTrack*);
360 void textTrackKindChanged(TextTrack&) override;
361 void textTrackModeChanged(TextTrack&) override;
362 void textTrackAddCues(TextTrack&, const TextTrackCueList&) override;
363 void textTrackRemoveCues(TextTrack&, const TextTrackCueList&) override;
364 void textTrackAddCue(TextTrack&, TextTrackCue&) override;
365 void textTrackRemoveCue(TextTrack&, TextTrackCue&) override;
368 void videoTrackSelectedChanged(VideoTrack&) final;
370 bool requiresTextTrackRepresentation() const;
371 void setTextTrackRepresentation(TextTrackRepresentation*);
372 void syncTextTrackBounds();
375 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
376 void webkitShowPlaybackTargetPicker();
377 bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
378 bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
380 void wirelessRoutesAvailableDidChange() override;
381 bool canPlayToWirelessPlaybackTarget() const override;
382 bool isPlayingToWirelessPlaybackTarget() const override;
383 void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
384 void setShouldPlayToPlaybackTarget(bool) override;
386 bool webkitCurrentPlaybackTargetIsWireless() const;
388 // EventTarget function.
389 // Both Node (via HTMLElement) and ActiveDOMObject define this method, which
390 // causes an ambiguity error at compile time. This class's constructor
391 // ensures that both implementations return document, so return the result
392 // of one of them here.
393 using HTMLElement::scriptExecutionContext;
395 bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
397 WEBCORE_EXPORT bool isFullscreen() const override;
398 bool isStandardFullscreen() const;
399 void toggleStandardFullscreenState();
401 using MediaPlayerEnums::VideoFullscreenMode;
402 VideoFullscreenMode fullscreenMode() const { return m_videoFullscreenMode; }
403 virtual void fullscreenModeChanged(VideoFullscreenMode);
405 void enterFullscreen(VideoFullscreenMode);
406 void enterFullscreen() override;
407 WEBCORE_EXPORT void exitFullscreen();
409 bool hasClosedCaptions() const override;
410 bool closedCaptionsVisible() const override;
411 void setClosedCaptionsVisible(bool) override;
413 MediaControls* mediaControls() const;
415 void sourceWasRemoved(HTMLSourceElement&);
416 void sourceWasAdded(HTMLSourceElement&);
418 void privateBrowsingStateDidChange() override;
420 // Media cache management.
421 WEBCORE_EXPORT static void setMediaCacheDirectory(const String&);
422 WEBCORE_EXPORT static const String& mediaCacheDirectory();
423 WEBCORE_EXPORT static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&);
424 WEBCORE_EXPORT static void clearMediaCache(const String&, std::chrono::system_clock::time_point modifiedSince = { });
425 WEBCORE_EXPORT static void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&);
426 static void resetMediaEngines();
428 bool isPlaying() const { return m_playing; }
430 bool hasPendingActivity() const override;
432 #if ENABLE(WEB_AUDIO)
433 MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; }
434 void setAudioSourceNode(MediaElementAudioSourceNode*);
436 AudioSourceProvider* audioSourceProvider();
439 using HTMLMediaElementEnums::InvalidURLAction;
440 bool isSafeToLoadURL(const URL&, InvalidURLAction);
442 const String& mediaGroup() const;
443 void setMediaGroup(const String&);
445 MediaController* controller() const;
446 void setController(RefPtr<MediaController>&&);
448 MediaController* controllerForBindings() const { return controller(); }
449 void setControllerForBindings(MediaController*);
451 void enteredOrExitedFullscreen() { configureMediaControls(); }
453 unsigned long long fileSize() const;
455 void mediaLoadingFailed(MediaPlayerEnums::NetworkState);
456 void mediaLoadingFailedFatally(MediaPlayerEnums::NetworkState);
458 #if ENABLE(MEDIA_SESSION)
459 WEBCORE_EXPORT double playerVolume() const;
461 const String& kind() const { return m_kind; }
462 void setKind(const String& kind) { m_kind = kind; }
464 MediaSession* session() const;
465 void setSession(MediaSession*);
467 void setShouldDuck(bool);
469 static HTMLMediaElement* elementWithID(uint64_t);
470 uint64_t elementID() const { return m_elementID; }
473 #if ENABLE(MEDIA_SOURCE)
474 RefPtr<VideoPlaybackQuality> getVideoPlaybackQuality();
477 MediaPlayerEnums::Preload preloadValue() const { return m_preload; }
478 MediaElementSession& mediaSession() const { return *m_mediaSession; }
480 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
481 void pageScaleFactorChanged();
482 void userInterfaceLayoutDirectionChanged();
483 WEBCORE_EXPORT String getCurrentMediaControlsStatus();
485 MediaControlsHost* mediaControlsHost() { return m_mediaControlsHost.get(); }
488 bool isDisablingSleep() const { return m_sleepDisabler.get(); }
490 double maxBufferedTime() const;
492 MediaProducer::MediaStateFlags mediaState() const override;
494 void layoutSizeChanged();
495 void visibilityDidChange();
497 void allowsMediaDocumentInlinePlaybackChanged();
498 void updateShouldPlay();
500 RenderMedia* renderer() const;
502 void resetPlaybackSessionState();
503 bool isVisibleInViewport() const;
504 bool hasEverNotifiedAboutPlaying() const;
505 void setShouldDelayLoadEvent(bool);
507 bool hasEverHadAudio() const { return m_hasEverHadAudio; }
508 bool hasEverHadVideo() const { return m_hasEverHadVideo; }
510 double playbackStartedTime() const { return m_playbackStartedTime; }
512 bool isTemporarilyAllowingInlinePlaybackAfterFullscreen() const {return m_temporarilyAllowingInlinePlaybackAfterFullscreen; }
514 void isVisibleInViewportChanged();
515 void updateRateChangeRestrictions();
517 WEBCORE_EXPORT const MediaResourceLoader* lastMediaResourceLoaderForTesting() const;
519 #if ENABLE(MEDIA_STREAM)
520 void mediaStreamCaptureStarted() { resumeAutoplaying(); }
521 bool hasMediaStreamSrcObject() const { return !!m_mediaStreamSrcObject; }
524 bool supportsSeeking() const override;
527 HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser);
528 virtual ~HTMLMediaElement();
530 void parseAttribute(const QualifiedName&, const AtomicString&) override;
531 void finishParsingChildren() override;
532 bool isURLAttribute(const Attribute&) const override;
533 void willAttachRenderers() override;
534 void didAttachRenderers() override;
535 void willDetachRenderers() override;
536 void didDetachRenderers() override;
538 void didMoveToNewDocument(Document& oldDocument, Document& newDocument) override;
540 enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
541 DisplayMode displayMode() const { return m_displayMode; }
542 virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
544 bool isMediaElement() const final { return true; }
546 #if ENABLE(VIDEO_TRACK)
547 bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0 || !m_textTracks || !m_cueTree.size(); }
548 void beginIgnoringTrackDisplayUpdateRequests();
549 void endIgnoringTrackDisplayUpdateRequests();
552 RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
554 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
555 bool mediaControlsDependOnPageScaleFactor() const { return m_mediaControlsDependOnPageScaleFactor; }
556 void setMediaControlsDependOnPageScaleFactor(bool);
557 void updateMediaControlsAfterPresentationModeChange();
560 void scheduleEvent(const AtomicString& eventName);
563 void createMediaPlayer();
565 bool alwaysCreateUserAgentShadowRoot() const override { return true; }
567 bool supportsFocus() const override;
568 bool isMouseFocusable() const override;
569 bool rendererIsNeeded(const RenderStyle&) override;
570 bool childShouldCreateRenderer(const Node&) const override;
571 InsertionNotificationRequest insertedInto(ContainerNode&) override;
572 void finishedInsertingSubtree() override;
573 void removedFrom(ContainerNode&) override;
574 void didRecalcStyle(Style::Change) override;
576 void willBecomeFullscreenElement() override;
577 void didBecomeFullscreenElement() override;
578 void willStopBeingFullscreenElement() override;
580 // ActiveDOMObject API.
581 const char* activeDOMObjectName() const override;
582 bool canSuspendForDocumentSuspension() const override;
583 void suspend(ReasonForSuspension) override;
584 void resume() override;
585 void stop() override;
586 void stopWithoutDestroyingMediaPlayer();
587 void contextDestroyed() override;
589 void mediaVolumeDidChange() override;
591 void visibilityStateChanged() override;
593 virtual void updateDisplayState() { }
595 void setReadyState(MediaPlayerEnums::ReadyState);
596 void setNetworkState(MediaPlayerEnums::NetworkState);
598 double effectivePlaybackRate() const;
599 double requestedPlaybackRate() const;
601 void mediaPlayerNetworkStateChanged(MediaPlayer*) override;
602 void mediaPlayerReadyStateChanged(MediaPlayer*) override;
603 void mediaPlayerTimeChanged(MediaPlayer*) override;
604 void mediaPlayerVolumeChanged(MediaPlayer*) override;
605 void mediaPlayerMuteChanged(MediaPlayer*) override;
606 void mediaPlayerDurationChanged(MediaPlayer*) override;
607 void mediaPlayerRateChanged(MediaPlayer*) override;
608 void mediaPlayerPlaybackStateChanged(MediaPlayer*) override;
609 void mediaPlayerSawUnsupportedTracks(MediaPlayer*) override;
610 void mediaPlayerResourceNotSupported(MediaPlayer*) override;
611 void mediaPlayerRepaint(MediaPlayer*) override;
612 void mediaPlayerSizeChanged(MediaPlayer*) override;
613 bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) override;
614 void mediaPlayerRenderingModeChanged(MediaPlayer*) override;
615 bool mediaPlayerAcceleratedCompositingEnabled() override;
616 void mediaPlayerEngineUpdated(MediaPlayer*) override;
617 void mediaEngineWasUpdated();
619 void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) override;
620 void mediaPlayerCharacteristicChanged(MediaPlayer*) override;
622 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
623 RefPtr<ArrayBuffer> mediaPlayerCachedKeyForKeyId(const String& keyId) const override;
624 bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override;
625 String mediaPlayerMediaKeysStorageDirectory() const override;
628 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
629 void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override;
630 void enqueuePlaybackTargetAvailabilityChangedEvent();
632 using EventTarget::dispatchEvent;
633 bool dispatchEvent(Event&) override;
636 #if ENABLE(MEDIA_SESSION)
637 void setSessionInternal(MediaSession&);
640 String mediaPlayerReferrer() const override;
641 String mediaPlayerUserAgent() const override;
643 bool mediaPlayerNeedsSiteSpecificHacks() const override;
644 String mediaPlayerDocumentHost() const override;
646 void mediaPlayerEnterFullscreen() override;
647 void mediaPlayerExitFullscreen() override;
648 bool mediaPlayerIsFullscreen() const override;
649 bool mediaPlayerIsFullscreenPermitted() const override;
650 bool mediaPlayerIsVideo() const override;
651 LayoutRect mediaPlayerContentBoxRect() const override;
652 float mediaPlayerContentsScale() const override;
653 void mediaPlayerSetSize(const IntSize&) override;
654 void mediaPlayerPause() override;
655 void mediaPlayerPlay() override;
656 bool mediaPlayerPlatformVolumeConfigurationRequired() const override;
657 bool mediaPlayerIsPaused() const override;
658 bool mediaPlayerIsLooping() const override;
659 CachedResourceLoader* mediaPlayerCachedResourceLoader() override;
660 RefPtr<PlatformMediaResourceLoader> mediaPlayerCreateResourceLoader() override;
661 bool mediaPlayerShouldUsePersistentCache() const override;
662 const String& mediaPlayerMediaCacheDirectory() const override;
664 #if PLATFORM(WIN) && USE(AVFOUNDATION)
665 GraphicsDeviceAdapter* mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const override;
668 void mediaPlayerActiveSourceBuffersChanged(const MediaPlayer*) override;
670 bool mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge&) override;
671 void mediaPlayerHandlePlaybackCommand(PlatformMediaSession::RemoteControlCommandType command) override { didReceiveRemoteControlCommand(command, nullptr); }
672 String sourceApplicationIdentifier() const override;
673 String mediaPlayerSourceApplicationIdentifier() const override { return sourceApplicationIdentifier(); }
674 Vector<String> mediaPlayerPreferredAudioCharacteristics() const override;
677 String mediaPlayerNetworkInterfaceName() const override;
678 bool mediaPlayerGetRawCookies(const URL&, Vector<Cookie>&) const override;
681 bool mediaPlayerIsInMediaDocument() const final;
682 void mediaPlayerEngineFailedToLoad() const final;
684 double mediaPlayerRequestedPlaybackRate() const final;
685 VideoFullscreenMode mediaPlayerFullscreenMode() const final { return fullscreenMode(); }
686 bool mediaPlayerShouldDisableSleep() const final { return shouldDisableSleep() == SleepType::Display; }
687 bool mediaPlayerShouldCheckHardwareSupport() const final;
688 const Vector<ContentType>& mediaContentTypesRequiringHardwareSupport() const final;
691 void requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback&) final;
694 void pendingActionTimerFired();
695 void progressEventTimerFired();
696 void playbackProgressTimerFired();
697 void scanTimerFired();
699 void startPlaybackProgressTimer();
700 void startProgressEventTimer();
701 void stopPeriodicTimers();
703 void seek(const MediaTime&);
704 void seekInternal(const MediaTime&);
705 void seekWithTolerance(const MediaTime&, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance, bool fromDOM);
708 void addPlayedRange(const MediaTime& start, const MediaTime& end);
710 void scheduleTimeupdateEvent(bool periodicEvent);
711 virtual void scheduleResizeEvent() { }
712 virtual void scheduleResizeEventIfSizeChanged() { }
714 void selectMediaResource();
715 void loadResource(const URL&, ContentType&, const String& keySystem);
716 void scheduleNextSourceChild();
717 void loadNextSourceChild();
718 void userCancelledLoad();
719 void clearMediaPlayer(DelayedActionType flags);
720 bool havePotentialSourceChild();
721 void noneSupported();
722 void cancelPendingEventsAndCallbacks();
723 void waitForSourceChange();
724 void prepareToPlay();
726 URL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction);
728 #if ENABLE(VIDEO_TRACK)
729 void updateActiveTextTrackCues(const MediaTime&);
730 HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
732 enum ReconfigureMode {
736 void markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMode);
737 void captionPreferencesChanged() override;
740 // These "internal" functions do not check user gesture restrictions.
742 void pauseInternal();
744 void prepareForLoad();
745 void allowVideoRendering();
747 bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
748 void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
749 void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
751 enum class UpdateState { Asynchronously, Synchronously };
753 void updatePlayState(UpdateState updateState = UpdateState::Synchronously);
755 void setPlaying(bool);
756 bool potentiallyPlaying() const;
757 bool endedPlayback() const;
758 bool stoppedDueToErrors() const;
759 bool pausedForUserInteraction() const;
760 bool couldPlayIfEnoughData() const;
761 void dispatchPlayPauseEventsIfNeedsQuirks();
762 SuccessOr<MediaPlaybackDenialReason> canTransitionFromAutoplayToPlay() const;
764 enum class PlaybackWithoutUserGesture { None, Started, Prevented };
765 void setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture);
766 void userDidInterfereWithAutoplay();
767 void handleAutoplayEvent(AutoplayEvent);
769 MediaTime minTimeSeekable() const;
770 MediaTime maxTimeSeekable() const;
772 // Pauses playback without changing any states or generating events
773 void setPausedInternal(bool);
775 void setPlaybackRateInternal(double);
777 void mediaCanStart(Document&) final;
779 void invalidateCachedTime() const;
780 void refreshCachedTime() const;
782 bool hasMediaControls() const;
783 bool createMediaControls();
784 void configureMediaControls();
786 void prepareMediaFragmentURI();
787 void applyMediaFragmentURI();
789 void changeNetworkStateFromLoadingToIdle();
791 void removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask = MediaElementSession::AllRestrictions);
793 void updateMediaController();
794 bool isBlocked() const;
795 bool isBlockedOnMediaController() const;
796 bool hasCurrentSrc() const override { return !m_currentSrc.isEmpty(); }
797 bool isLiveStream() const override { return movieLoadType() == MediaPlayerEnums::LiveStream; }
799 void updateSleepDisabling();
800 enum class SleepType {
805 SleepType shouldDisableSleep() const;
807 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
808 void didAddUserAgentShadowRoot(ShadowRoot*) override;
809 DOMWrapperWorld& ensureIsolatedWorld();
810 bool ensureMediaControlsInjectedScript();
813 PlatformMediaSession::MediaType mediaType() const override;
814 PlatformMediaSession::MediaType presentationType() const override;
815 PlatformMediaSession::DisplayType displayType() const override;
816 PlatformMediaSession::CharacteristicsFlags characteristics() const final;
818 void suspendPlayback() override;
819 void resumeAutoplaying() override;
820 void mayResumePlayback(bool shouldResume) override;
821 String mediaSessionTitle() const override;
822 double mediaSessionDuration() const override { return duration(); }
823 double mediaSessionCurrentTime() const override { return currentTime(); }
824 bool canReceiveRemoteControlCommands() const override { return true; }
825 void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) override;
826 bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override;
827 bool shouldOverrideBackgroundLoadingRestriction() const override;
828 bool canProduceAudio() const final;
829 bool processingUserGestureForMedia() const final;
830 bool isSuspended() const final;
832 void pageMutedStateDidChange() override;
834 #if USE(AUDIO_SESSION) && PLATFORM(MAC)
835 void hardwareMutedStateDidChange(AudioSession*) final;
838 bool effectiveMuted() const;
840 void registerWithDocument(Document&);
841 void unregisterWithDocument(Document&);
843 void updateCaptionContainer();
844 void ensureMediaControlsShadowRoot();
846 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
847 void prepareForDocumentSuspension() final;
848 void resumeFromDocumentSuspension() final;
850 void updateMediaState(UpdateState updateState = UpdateState::Synchronously);
851 bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; }
854 bool isVideoTooSmallForInlinePlayback();
855 void updateShouldAutoplay();
857 void pauseAfterDetachedTask();
858 void updatePlaybackControlsManager();
859 void scheduleUpdatePlaybackControlsManager();
860 void playbackControlsManagerBehaviorRestrictionsTimerFired();
862 void updateRenderer();
864 void updatePageScaleFactorJSProperty();
865 void updateUsesLTRUserInterfaceLayoutDirectionJSProperty();
866 void setControllerJSProperty(const char*, JSC::JSValue);
868 void addBehaviorRestrictionsOnEndIfNecessary();
869 void handleSeekToPlaybackPosition(double);
870 void seekToPlaybackPositionEndedTimerFired();
872 WeakPtrFactory<HTMLMediaElement> m_weakFactory;
873 Timer m_pendingActionTimer;
874 Timer m_progressEventTimer;
875 Timer m_playbackProgressTimer;
877 Timer m_playbackControlsManagerBehaviorRestrictionsTimer;
878 Timer m_seekToPlaybackPositionEndedTimer;
879 GenericTaskQueue<Timer> m_seekTaskQueue;
880 GenericTaskQueue<Timer> m_shadowDOMTaskQueue;
881 GenericTaskQueue<Timer> m_promiseTaskQueue;
882 GenericTaskQueue<Timer> m_pauseAfterDetachedTaskQueue;
883 GenericTaskQueue<Timer> m_updatePlaybackControlsManagerQueue;
884 GenericTaskQueue<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue;
885 GenericTaskQueue<Timer> m_resourceSelectionTaskQueue;
886 RefPtr<TimeRanges> m_playedTimeRanges;
887 GenericEventQueue m_asyncEventQueue;
889 Vector<DOMPromiseDeferred<void>> m_pendingPlayPromises;
891 double m_requestedPlaybackRate { 1 };
892 double m_reportedPlaybackRate { 1 };
893 double m_defaultPlaybackRate { 1 };
894 bool m_webkitPreservesPitch { true };
895 NetworkState m_networkState { NETWORK_EMPTY };
896 ReadyState m_readyState { HAVE_NOTHING };
897 ReadyState m_readyStateMaximum { HAVE_NOTHING };
900 RefPtr<MediaError> m_error;
903 PendingSeek(const MediaTime& now, const MediaTime& targetTime, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance)
905 , targetTime(targetTime)
906 , negativeTolerance(negativeTolerance)
907 , positiveTolerance(positiveTolerance)
911 MediaTime targetTime;
912 MediaTime negativeTolerance;
913 MediaTime positiveTolerance;
915 std::unique_ptr<PendingSeek> m_pendingSeek;
916 SeekType m_pendingSeekType { NoSeek };
918 double m_volume { 1 };
919 bool m_volumeInitialized { false };
920 MediaTime m_lastSeekTime;
922 double m_previousProgressTime { std::numeric_limits<double>::max() };
923 double m_playbackStartedTime { 0 };
925 // The last time a timeupdate event was sent (based on monotonic clock).
926 MonotonicTime m_clockTimeAtLastUpdateEvent;
928 // The last time a timeupdate event was sent in movie time.
929 MediaTime m_lastTimeUpdateEventMovieTime;
932 enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
933 LoadState m_loadState { WaitingForSource };
934 RefPtr<HTMLSourceElement> m_currentSourceNode;
935 RefPtr<HTMLSourceElement> m_nextChildNodeToConsider;
937 VideoFullscreenMode m_videoFullscreenMode { VideoFullscreenModeNone };
938 bool m_preparedForInline;
939 WTF::Function<void()> m_preparedForInlineCompletionHandler;
941 bool m_temporarilyAllowingInlinePlaybackAfterFullscreen { false };
943 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
944 RetainPtr<PlatformLayer> m_videoFullscreenLayer;
945 FloatRect m_videoFullscreenFrame;
946 MediaPlayerEnums::VideoGravity m_videoFullscreenGravity { MediaPlayer::VideoGravityResizeAspect };
949 RefPtr<MediaPlayer> m_player;
951 MediaPlayerEnums::Preload m_preload { MediaPlayer::Auto };
953 DisplayMode m_displayMode { Unknown };
955 // Counter incremented while processing a callback from the media player, so we can avoid
956 // calling the media engine recursively.
957 int m_processingMediaPlayerCallback { 0 };
959 #if ENABLE(MEDIA_SESSION)
961 RefPtr<MediaSession> m_session;
962 bool m_shouldDuck { false };
963 uint64_t m_elementID;
966 #if ENABLE(MEDIA_SOURCE)
967 RefPtr<MediaSource> m_mediaSource;
968 unsigned m_droppedVideoFrames { 0 };
971 mutable MediaTime m_cachedTime;
972 mutable double m_clockTimeAtLastCachedTimeUpdate { 0 };
973 mutable double m_minimumClockTimeToUpdateCachedTime { 0 };
975 MediaTime m_fragmentStartTime;
976 MediaTime m_fragmentEndTime;
978 using PendingActionFlags = unsigned;
979 PendingActionFlags m_pendingActionFlags { 0 };
981 enum ActionAfterScanType { Nothing, Play, Pause };
982 ActionAfterScanType m_actionAfterScan { Nothing };
984 enum ScanType { Seek, Scan };
985 ScanType m_scanType { Scan };
986 ScanDirection m_scanDirection { Forward };
988 bool m_firstTimePlaying : 1;
990 bool m_isWaitingUntilMediaCanStart : 1;
991 bool m_shouldDelayLoadEvent : 1;
992 bool m_haveFiredLoadedData : 1;
993 bool m_inActiveDocument : 1;
994 bool m_autoplaying : 1;
996 bool m_explicitlyMuted : 1;
997 bool m_initiallyMuted : 1;
1000 bool m_seekRequested : 1;
1002 // data has not been loaded since sending a "stalled" event
1003 bool m_sentStalledEvent : 1;
1005 // time has not changed since sending an "ended" event
1006 bool m_sentEndEvent : 1;
1008 bool m_pausedInternal : 1;
1010 bool m_closedCaptionsVisible : 1;
1011 bool m_webkitLegacyClosedCaptionOverride : 1;
1012 bool m_completelyLoaded : 1;
1013 bool m_havePreparedToPlay : 1;
1014 bool m_parsingInProgress : 1;
1015 bool m_elementIsHidden : 1;
1016 bool m_creatingControls : 1;
1017 bool m_receivedLayoutSizeChanged : 1;
1018 bool m_hasEverNotifiedAboutPlaying : 1;
1020 bool m_hasEverHadAudio : 1;
1021 bool m_hasEverHadVideo : 1;
1023 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1024 bool m_mediaControlsDependOnPageScaleFactor : 1;
1025 bool m_haveSetUpCaptionContainer : 1;
1028 bool m_isScrubbingRemotely : 1;
1030 #if ENABLE(VIDEO_TRACK)
1031 bool m_tracksAreReady : 1;
1032 bool m_haveVisibleTextTrack : 1;
1033 bool m_processingPreferenceChange : 1;
1035 PlaybackWithoutUserGesture m_playbackWithoutUserGesture { PlaybackWithoutUserGesture::None };
1036 std::optional<MediaTime> m_playbackWithoutUserGestureStartedTime;
1038 String m_subtitleTrackLanguage;
1039 MediaTime m_lastTextTrackUpdateTime { -1, 1 };
1041 CaptionUserPreferences::CaptionDisplayMode m_captionDisplayMode { CaptionUserPreferences::Automatic };
1043 RefPtr<AudioTrackList> m_audioTracks;
1044 RefPtr<TextTrackList> m_textTracks;
1045 RefPtr<VideoTrackList> m_videoTracks;
1046 Vector<RefPtr<TextTrack>> m_textTracksWhenResourceSelectionBegan;
1048 CueIntervalTree m_cueTree;
1050 CueList m_currentlyActiveCues;
1051 int m_ignoreTrackDisplayUpdate { 0 };
1053 bool m_requireCaptionPreferencesChangedCallbacks { false };
1056 #if ENABLE(WEB_AUDIO)
1057 // This is a weak reference, since m_audioSourceNode holds a reference to us.
1058 // The value is set just after the MediaElementAudioSourceNode is created.
1059 // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode().
1060 MediaElementAudioSourceNode* m_audioSourceNode { nullptr };
1063 String m_mediaGroup;
1064 friend class MediaController;
1065 RefPtr<MediaController> m_mediaController;
1067 std::unique_ptr<SleepDisabler> m_sleepDisabler;
1069 WeakPtr<const MediaResourceLoader> m_lastMediaResourceLoaderForTesting;
1071 friend class TrackDisplayUpdateScope;
1073 RefPtr<Blob> m_blob;
1074 MediaProvider m_mediaProvider;
1076 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
1077 RefPtr<WebKitMediaKeys> m_webKitMediaKeys;
1080 std::unique_ptr<MediaElementSession> m_mediaSession;
1081 size_t m_reportedExtraMemoryCost { 0 };
1083 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1084 friend class MediaControlsHost;
1085 RefPtr<MediaControlsHost> m_mediaControlsHost;
1086 RefPtr<DOMWrapperWorld> m_isolatedWorld;
1089 #if ENABLE(MEDIA_STREAM)
1090 RefPtr<MediaStream> m_mediaStreamSrcObject;
1091 bool m_settingMediaStreamSrcObject { false };
1094 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
1095 MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
1096 bool m_hasPlaybackTargetAvailabilityListeners { false };
1097 bool m_failedToPlayToWirelessTarget { false };
1098 bool m_isPlayingToWirelessTarget { false };
1102 #if ENABLE(VIDEO_TRACK) && !defined(NDEBUG)
1104 // Template specialization required by PodIntervalTree in debug mode.
1105 template <> struct ValueToString<TextTrackCue*> {
1106 static String string(TextTrackCue* const& cue)
1109 if (cue->isRenderable())
1110 text = toVTTCue(cue)->text();
1111 return String::format("%p id=%s interval=%s-->%s cue=%s)", cue, cue->id().utf8().data(), toString(cue->startTime()).utf8().data(), toString(cue->endTime()).utf8().data(), text.utf8().data());
1119 template<> struct ValueToString<MediaTime> {
1120 static String string(const MediaTime& time)
1122 return toString(time);
1128 } // namespace WebCore
1130 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLMediaElement)
1131 static bool isType(const WebCore::Element& element) { return element.isMediaElement(); }
1132 static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
1133 SPECIALIZE_TYPE_TRAITS_END()