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 "GenericEventQueue.h"
32 #include "GenericTaskQueue.h"
33 #include "HTMLElement.h"
34 #include "HTMLMediaElementEnums.h"
35 #include "MediaCanStartListener.h"
36 #include "MediaControllerInterface.h"
37 #include "MediaElementSession.h"
38 #include "MediaProducer.h"
39 #include "UserInterfaceLayoutDirection.h"
41 #if ENABLE(VIDEO_TRACK)
42 #include "AudioTrack.h"
43 #include "CaptionUserPreferences.h"
44 #include "PODIntervalTree.h"
45 #include "TextTrack.h"
46 #include "TextTrackCue.h"
48 #include "VideoTrack.h"
52 #include <wtf/StringPrintStream.h>
57 class AudioSourceProvider;
59 class AudioTrackPrivate;
61 class DeferredPromise;
62 class DisplaySleepDisabler;
64 class HTMLSourceElement;
65 class HTMLTrackElement;
66 class InbandTextTrackPrivate;
67 class MediaController;
69 class MediaControlsHost;
70 class MediaElementAudioSourceNode;
78 class ScriptExecutionContext;
82 class VideoPlaybackQuality;
84 class VideoTrackPrivate;
85 class WebKitMediaKeys;
87 template<typename> class DOMPromise;
89 #if ENABLE(VIDEO_TRACK)
90 using CueIntervalTree = PODIntervalTree<MediaTime, TextTrackCue*>;
91 using CueInterval = CueIntervalTree::IntervalType;
92 using CueList = Vector<CueInterval>;
95 class HTMLMediaElement
97 , public ActiveDOMObject
98 , public MediaControllerInterface
99 , public MediaPlayerSupportsTypeClient
100 , public PlatformMediaSessionClient
101 , private MediaCanStartListener
102 , private MediaPlayerClient
103 , private MediaProducer
104 #if ENABLE(VIDEO_TRACK)
105 , private AudioTrackClient
106 , private TextTrackClient
107 , private VideoTrackClient
111 MediaPlayer* player() const { return m_player.get(); }
113 virtual bool isVideo() const { return false; }
114 bool hasVideo() const override { return false; }
115 bool hasAudio() const override;
117 static HashSet<HTMLMediaElement*>& allMediaElements();
119 static HTMLMediaElement* bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose);
121 void rewind(double timeDelta);
122 WEBCORE_EXPORT void returnToRealtime() override;
124 // Eventually overloaded in HTMLVideoElement
125 bool supportsFullscreen(HTMLMediaElementEnums::VideoFullscreenMode) const override { return false; };
127 bool supportsScanning() const override;
129 bool canSaveMediaData() const;
131 bool doesHaveAttribute(const AtomicString&, AtomicString* value = nullptr) const override;
133 WEBCORE_EXPORT PlatformMedia platformMedia() const;
134 PlatformLayer* platformLayer() const;
135 bool isVideoLayerInline();
136 void setPreparedToReturnVideoLayerToInline(bool);
137 void waitForPreparedForInlineThen(std::function<void()> completionHandler = [] { });
138 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
139 void setVideoFullscreenLayer(PlatformLayer*, std::function<void()> completionHandler = [] { });
140 PlatformLayer* videoFullscreenLayer() const { return m_videoFullscreenLayer.get(); }
141 void setVideoFullscreenFrame(FloatRect);
142 void setVideoFullscreenGravity(MediaPlayerEnums::VideoGravity);
143 MediaPlayerEnums::VideoGravity videoFullscreenGravity() const { return m_videoFullscreenGravity; }
146 using HTMLMediaElementEnums::DelayedActionType;
147 void scheduleDelayedAction(DelayedActionType);
148 void scheduleResolvePendingPlayPromises();
149 void rejectPendingPlayPromises(DOMError&);
150 void resolvePendingPlayPromises();
151 void scheduleNotifyAboutPlaying();
152 void notifyAboutPlaying();
154 MediaPlayerEnums::MovieLoadType movieLoadType() const;
156 bool inActiveDocument() const { return m_inActiveDocument; }
158 const Document* hostingDocument() const override { return &document(); }
162 WEBCORE_EXPORT MediaError* error() const;
164 void setSrc(const String&);
165 const URL& currentSrc() const { return m_currentSrc; }
167 #if ENABLE(MEDIA_STREAM)
168 MediaStream* srcObject() const { return m_mediaStreamSrcObject.get(); }
169 void setSrcObject(ScriptExecutionContext&, MediaStream*);
172 WEBCORE_EXPORT void setCrossOrigin(const AtomicString&);
173 WEBCORE_EXPORT String crossOrigin() const;
176 using HTMLMediaElementEnums::NetworkState;
177 WEBCORE_EXPORT NetworkState networkState() const;
179 WEBCORE_EXPORT String preload() const;
180 WEBCORE_EXPORT void setPreload(const String&);
182 Ref<TimeRanges> buffered() const override;
183 WEBCORE_EXPORT void load();
184 WEBCORE_EXPORT String canPlayType(const String& mimeType) const;
187 using HTMLMediaElementEnums::ReadyState;
188 ReadyState readyState() const override;
189 WEBCORE_EXPORT bool seeking() const;
192 WEBCORE_EXPORT double currentTime() const override;
193 void setCurrentTime(double) override;
194 double currentTimeForBindings() const { return currentTime(); }
195 WEBCORE_EXPORT ExceptionOr<void> setCurrentTimeForBindings(double);
196 WEBCORE_EXPORT double getStartDate() const;
197 WEBCORE_EXPORT double duration() const override;
198 WEBCORE_EXPORT bool paused() const override;
199 double defaultPlaybackRate() const override;
200 void setDefaultPlaybackRate(double) override;
201 WEBCORE_EXPORT double playbackRate() const override;
202 void setPlaybackRate(double) override;
204 // MediaTime versions of playback state
205 MediaTime currentMediaTime() const;
206 void setCurrentTime(const MediaTime&);
207 MediaTime durationMediaTime() const;
208 WEBCORE_EXPORT void fastSeek(const MediaTime&);
210 void updatePlaybackRate();
211 WEBCORE_EXPORT bool webkitPreservesPitch() const;
212 WEBCORE_EXPORT void setWebkitPreservesPitch(bool);
213 Ref<TimeRanges> played() override;
214 Ref<TimeRanges> seekable() const override;
215 WEBCORE_EXPORT bool ended() const;
216 bool autoplay() const;
217 bool isAutoplaying() const { return m_autoplaying; }
219 void setLoop(bool b);
221 void play(DOMPromise<void>&&);
223 WEBCORE_EXPORT void play() override;
224 WEBCORE_EXPORT void pause() override;
225 void setShouldBufferData(bool) override;
226 WEBCORE_EXPORT void fastSeek(double);
227 double minFastReverseRate() const;
228 double maxFastForwardRate() const;
230 void purgeBufferedDataIfPossible();
233 WEBCORE_EXPORT bool webkitHasClosedCaptions() const;
234 WEBCORE_EXPORT bool webkitClosedCaptionsVisible() const;
235 WEBCORE_EXPORT void setWebkitClosedCaptionsVisible(bool);
237 bool elementIsHidden() const override { return m_elementIsHidden; }
239 #if ENABLE(MEDIA_STATISTICS)
241 unsigned webkitAudioDecodedByteCount() const;
242 unsigned webkitVideoDecodedByteCount() const;
245 #if ENABLE(MEDIA_SOURCE)
247 void detachMediaSource();
248 void incrementDroppedFrameCount() { ++m_droppedVideoFrames; }
249 size_t maximumSourceBufferSize(const SourceBuffer&) const;
252 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
253 WebKitMediaKeys* webkitKeys() const { return m_webKitMediaKeys.get(); }
254 void webkitSetMediaKeys(WebKitMediaKeys*);
259 #if ENABLE(ENCRYPTED_MEDIA)
260 MediaKeys* mediaKeys() const;
262 void setMediaKeys(MediaKeys*, Ref<DeferredPromise>&&);
266 WEBCORE_EXPORT bool controls() const;
267 WEBCORE_EXPORT void setControls(bool);
268 WEBCORE_EXPORT double volume() const override;
269 ExceptionOr<void> setVolume(double) override;
270 WEBCORE_EXPORT bool muted() const override;
271 WEBCORE_EXPORT void setMuted(bool) override;
273 WEBCORE_EXPORT void togglePlayState();
274 WEBCORE_EXPORT void beginScrubbing() override;
275 WEBCORE_EXPORT void endScrubbing() override;
277 void beginScanning(ScanDirection) override;
278 void endScanning() override;
279 double nextScanRate();
281 WEBCORE_EXPORT bool canPlay() const override;
283 double percentLoaded() const;
285 #if ENABLE(VIDEO_TRACK)
286 ExceptionOr<TextTrack&> addTextTrack(const String& kind, const String& label, const String& language);
288 AudioTrackList& audioTracks();
289 TextTrackList& textTracks();
290 VideoTrackList& videoTracks();
292 CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
294 void addAudioTrack(Ref<AudioTrack>&&);
295 void addTextTrack(Ref<TextTrack>&&);
296 void addVideoTrack(Ref<VideoTrack>&&);
297 void removeAudioTrack(AudioTrack&);
298 void removeTextTrack(TextTrack&, bool scheduleEvent = true);
299 void removeVideoTrack(VideoTrack&);
300 void forgetResourceSpecificTracks();
301 void closeCaptionTracksChanged();
302 void notifyMediaPlayerOfTextTrackChanges();
304 virtual void didAddTextTrack(HTMLTrackElement&);
305 virtual void didRemoveTextTrack(HTMLTrackElement&);
307 void mediaPlayerDidAddAudioTrack(AudioTrackPrivate&) final;
308 void mediaPlayerDidAddTextTrack(InbandTextTrackPrivate&) final;
309 void mediaPlayerDidAddVideoTrack(VideoTrackPrivate&) final;
310 void mediaPlayerDidRemoveAudioTrack(AudioTrackPrivate&) final;
311 void mediaPlayerDidRemoveTextTrack(InbandTextTrackPrivate&) final;
312 void mediaPlayerDidRemoveVideoTrack(VideoTrackPrivate&) final;
314 #if ENABLE(AVF_CAPTIONS)
315 Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources() final;
319 void configureTextTrackGroupForLanguage(const TrackGroup&) const;
320 void configureTextTracks();
321 void configureTextTrackGroup(const TrackGroup&);
323 void setSelectedTextTrack(TextTrack*);
325 bool textTracksAreReady() const;
326 using HTMLMediaElementEnums::TextTrackVisibilityCheckType;
327 void configureTextTrackDisplay(TextTrackVisibilityCheckType checkType = CheckTextTrackVisibility);
328 void updateTextTrackDisplay();
331 void audioTrackEnabledChanged(AudioTrack&) final;
333 void textTrackReadyStateChanged(TextTrack*);
336 void textTrackKindChanged(TextTrack&) override;
337 void textTrackModeChanged(TextTrack&) override;
338 void textTrackAddCues(TextTrack&, const TextTrackCueList&) override;
339 void textTrackRemoveCues(TextTrack&, const TextTrackCueList&) override;
340 void textTrackAddCue(TextTrack&, TextTrackCue&) override;
341 void textTrackRemoveCue(TextTrack&, TextTrackCue&) override;
344 void videoTrackSelectedChanged(VideoTrack&) final;
346 bool requiresTextTrackRepresentation() const;
347 void setTextTrackRepresentation(TextTrackRepresentation*);
348 void syncTextTrackBounds();
351 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
352 void webkitShowPlaybackTargetPicker();
353 bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
354 bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
356 void wirelessRoutesAvailableDidChange() override;
357 bool canPlayToWirelessPlaybackTarget() const override;
358 bool isPlayingToWirelessPlaybackTarget() const override;
359 void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
360 void setShouldPlayToPlaybackTarget(bool) override;
362 bool webkitCurrentPlaybackTargetIsWireless() const;
364 // EventTarget function.
365 // Both Node (via HTMLElement) and ActiveDOMObject define this method, which
366 // causes an ambiguity error at compile time. This class's constructor
367 // ensures that both implementations return document, so return the result
368 // of one of them here.
369 using HTMLElement::scriptExecutionContext;
371 bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
373 WEBCORE_EXPORT bool isFullscreen() const override;
374 bool isStandardFullscreen() const;
375 void toggleStandardFullscreenState();
377 using MediaPlayerEnums::VideoFullscreenMode;
378 VideoFullscreenMode fullscreenMode() const { return m_videoFullscreenMode; }
379 virtual void fullscreenModeChanged(VideoFullscreenMode);
381 void enterFullscreen(VideoFullscreenMode);
382 void enterFullscreen() override;
383 WEBCORE_EXPORT void exitFullscreen();
385 bool hasClosedCaptions() const override;
386 bool closedCaptionsVisible() const override;
387 void setClosedCaptionsVisible(bool) override;
389 MediaControls* mediaControls() const;
391 void sourceWasRemoved(HTMLSourceElement*);
392 void sourceWasAdded(HTMLSourceElement*);
394 void privateBrowsingStateDidChange() override;
396 // Media cache management.
397 WEBCORE_EXPORT static void setMediaCacheDirectory(const String&);
398 WEBCORE_EXPORT static const String& mediaCacheDirectory();
399 WEBCORE_EXPORT static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&);
400 WEBCORE_EXPORT static void clearMediaCache(const String&, std::chrono::system_clock::time_point modifiedSince = { });
401 WEBCORE_EXPORT static void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&);
402 static void resetMediaEngines();
404 bool isPlaying() const { return m_playing; }
406 bool hasPendingActivity() const override;
408 #if ENABLE(WEB_AUDIO)
409 MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; }
410 void setAudioSourceNode(MediaElementAudioSourceNode*);
412 AudioSourceProvider* audioSourceProvider();
415 using HTMLMediaElementEnums::InvalidURLAction;
416 bool isSafeToLoadURL(const URL&, InvalidURLAction);
418 const String& mediaGroup() const;
419 void setMediaGroup(const String&);
421 MediaController* controller() const;
422 void setController(RefPtr<MediaController>&&);
424 MediaController* controllerForBindings() const { return controller(); }
425 void setControllerForBindings(MediaController*);
427 void enteredOrExitedFullscreen() { configureMediaControls(); }
429 unsigned long long fileSize() const;
431 void mediaLoadingFailed(MediaPlayerEnums::NetworkState);
432 void mediaLoadingFailedFatally(MediaPlayerEnums::NetworkState);
434 #if ENABLE(MEDIA_SESSION)
435 WEBCORE_EXPORT double playerVolume() const;
437 const String& kind() const { return m_kind; }
438 void setKind(const String& kind) { m_kind = kind; }
440 MediaSession* session() const;
441 void setSession(MediaSession*);
443 void setShouldDuck(bool);
445 static HTMLMediaElement* elementWithID(uint64_t);
446 uint64_t elementID() const { return m_elementID; }
449 #if ENABLE(MEDIA_SOURCE)
450 RefPtr<VideoPlaybackQuality> getVideoPlaybackQuality();
453 MediaPlayerEnums::Preload preloadValue() const { return m_preload; }
454 MediaElementSession& mediaSession() const { return *m_mediaSession; }
456 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
457 void pageScaleFactorChanged();
458 void userInterfaceLayoutDirectionChanged();
459 WEBCORE_EXPORT String getCurrentMediaControlsStatus();
461 MediaControlsHost* mediaControlsHost() { return m_mediaControlsHost.get(); }
464 bool isDisablingSleep() const { return m_sleepDisabler.get(); }
466 double maxBufferedTime() const;
468 MediaProducer::MediaStateFlags mediaState() const override;
470 void layoutSizeChanged();
471 void visibilityDidChange();
473 void allowsMediaDocumentInlinePlaybackChanged();
474 void updateShouldPlay();
476 RenderMedia* renderer() const;
478 void resetPlaybackSessionState();
479 bool isVisibleInViewport() const;
480 bool hasEverNotifiedAboutPlaying() const;
481 void setShouldDelayLoadEvent(bool);
483 bool hasEverHadAudio() const { return m_hasEverHadAudio; }
484 bool hasEverHadVideo() const { return m_hasEverHadVideo; }
486 double playbackStartedTime() const { return m_playbackStartedTime; }
489 HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser);
490 virtual ~HTMLMediaElement();
492 void parseAttribute(const QualifiedName&, const AtomicString&) override;
493 void finishParsingChildren() override;
494 bool isURLAttribute(const Attribute&) const override;
495 void willAttachRenderers() override;
496 void didAttachRenderers() override;
497 void willDetachRenderers() override;
498 void didDetachRenderers() override;
500 void didMoveToNewDocument(Document& oldDocument) override;
502 enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
503 DisplayMode displayMode() const { return m_displayMode; }
504 virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
506 bool isMediaElement() const final { return true; }
508 #if ENABLE(VIDEO_TRACK)
509 bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0 || !m_textTracks || !m_cueTree.size(); }
510 void beginIgnoringTrackDisplayUpdateRequests();
511 void endIgnoringTrackDisplayUpdateRequests();
514 RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
516 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
517 bool mediaControlsDependOnPageScaleFactor() const { return m_mediaControlsDependOnPageScaleFactor; }
518 void setMediaControlsDependOnPageScaleFactor(bool);
519 void updateMediaControlsAfterPresentationModeChange();
522 void scheduleEvent(const AtomicString& eventName);
525 void createMediaPlayer();
527 bool alwaysCreateUserAgentShadowRoot() const override { return true; }
529 bool supportsFocus() const override;
530 bool isMouseFocusable() const override;
531 bool rendererIsNeeded(const RenderStyle&) override;
532 bool childShouldCreateRenderer(const Node&) const override;
533 InsertionNotificationRequest insertedInto(ContainerNode&) override;
534 void finishedInsertingSubtree() override;
535 void removedFrom(ContainerNode&) override;
536 void didRecalcStyle(Style::Change) override;
538 void willBecomeFullscreenElement() override;
539 void didBecomeFullscreenElement() override;
540 void willStopBeingFullscreenElement() override;
542 // ActiveDOMObject API.
543 const char* activeDOMObjectName() const override;
544 bool canSuspendForDocumentSuspension() const override;
545 void suspend(ReasonForSuspension) override;
546 void resume() override;
547 void stop() override;
548 void stopWithoutDestroyingMediaPlayer();
549 void contextDestroyed() override;
551 void mediaVolumeDidChange() override;
553 void visibilityStateChanged() override;
555 virtual void updateDisplayState() { }
557 void setReadyState(MediaPlayerEnums::ReadyState);
558 void setNetworkState(MediaPlayerEnums::NetworkState);
560 double effectivePlaybackRate() const;
561 double requestedPlaybackRate() const;
563 void mediaPlayerNetworkStateChanged(MediaPlayer*) override;
564 void mediaPlayerReadyStateChanged(MediaPlayer*) override;
565 void mediaPlayerTimeChanged(MediaPlayer*) override;
566 void mediaPlayerVolumeChanged(MediaPlayer*) override;
567 void mediaPlayerMuteChanged(MediaPlayer*) override;
568 void mediaPlayerDurationChanged(MediaPlayer*) override;
569 void mediaPlayerRateChanged(MediaPlayer*) override;
570 void mediaPlayerPlaybackStateChanged(MediaPlayer*) override;
571 void mediaPlayerSawUnsupportedTracks(MediaPlayer*) override;
572 void mediaPlayerResourceNotSupported(MediaPlayer*) override;
573 void mediaPlayerRepaint(MediaPlayer*) override;
574 void mediaPlayerSizeChanged(MediaPlayer*) override;
575 bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) override;
576 void mediaPlayerRenderingModeChanged(MediaPlayer*) override;
577 bool mediaPlayerAcceleratedCompositingEnabled() override;
578 void mediaPlayerEngineUpdated(MediaPlayer*) override;
579 void mediaEngineWasUpdated();
581 void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) override;
582 void mediaPlayerCharacteristicChanged(MediaPlayer*) override;
584 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
585 RefPtr<ArrayBuffer> mediaPlayerCachedKeyForKeyId(const String& keyId) const override;
586 bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override;
587 String mediaPlayerMediaKeysStorageDirectory() const override;
590 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
591 void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override;
592 void enqueuePlaybackTargetAvailabilityChangedEvent();
594 using EventTarget::dispatchEvent;
595 bool dispatchEvent(Event&) override;
598 #if ENABLE(MEDIA_SESSION)
599 void setSessionInternal(MediaSession&);
602 String mediaPlayerReferrer() const override;
603 String mediaPlayerUserAgent() const override;
605 bool mediaPlayerNeedsSiteSpecificHacks() const override;
606 String mediaPlayerDocumentHost() const override;
608 void mediaPlayerEnterFullscreen() override;
609 void mediaPlayerExitFullscreen() override;
610 bool mediaPlayerIsFullscreen() const override;
611 bool mediaPlayerIsFullscreenPermitted() const override;
612 bool mediaPlayerIsVideo() const override;
613 LayoutRect mediaPlayerContentBoxRect() const override;
614 float mediaPlayerContentsScale() const override;
615 void mediaPlayerSetSize(const IntSize&) override;
616 void mediaPlayerPause() override;
617 void mediaPlayerPlay() override;
618 bool mediaPlayerPlatformVolumeConfigurationRequired() const override;
619 bool mediaPlayerIsPaused() const override;
620 bool mediaPlayerIsLooping() const override;
621 CachedResourceLoader* mediaPlayerCachedResourceLoader() override;
622 RefPtr<PlatformMediaResourceLoader> mediaPlayerCreateResourceLoader() override;
623 bool mediaPlayerShouldUsePersistentCache() const override;
624 const String& mediaPlayerMediaCacheDirectory() const override;
626 #if PLATFORM(WIN) && USE(AVFOUNDATION)
627 GraphicsDeviceAdapter* mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const override;
630 void mediaPlayerActiveSourceBuffersChanged(const MediaPlayer*) override;
632 bool mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge&) override;
633 void mediaPlayerHandlePlaybackCommand(PlatformMediaSession::RemoteControlCommandType command) override { didReceiveRemoteControlCommand(command, nullptr); }
634 String sourceApplicationIdentifier() const override;
635 String mediaPlayerSourceApplicationIdentifier() const override { return sourceApplicationIdentifier(); }
636 Vector<String> mediaPlayerPreferredAudioCharacteristics() const override;
639 String mediaPlayerNetworkInterfaceName() const override;
640 bool mediaPlayerGetRawCookies(const URL&, Vector<Cookie>&) const override;
643 bool mediaPlayerIsInMediaDocument() const final;
644 void mediaPlayerEngineFailedToLoad() const final;
646 double mediaPlayerRequestedPlaybackRate() const final;
647 VideoFullscreenMode mediaPlayerFullscreenMode() const final { return fullscreenMode(); }
648 bool mediaPlayerShouldDisableSleep() const final { return shouldDisableSleep(); }
651 void requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback&) final;
654 void pendingActionTimerFired();
655 void progressEventTimerFired();
656 void playbackProgressTimerFired();
657 void scanTimerFired();
659 void startPlaybackProgressTimer();
660 void startProgressEventTimer();
661 void stopPeriodicTimers();
663 void seek(const MediaTime&);
664 void seekInternal(const MediaTime&);
665 void seekWithTolerance(const MediaTime&, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance, bool fromDOM);
668 void addPlayedRange(const MediaTime& start, const MediaTime& end);
670 void scheduleTimeupdateEvent(bool periodicEvent);
671 virtual void scheduleResizeEvent() { }
672 virtual void scheduleResizeEventIfSizeChanged() { }
674 void selectMediaResource();
675 void loadResource(const URL&, ContentType&, const String& keySystem);
676 void scheduleNextSourceChild();
677 void loadNextSourceChild();
678 void userCancelledLoad();
679 void clearMediaPlayer(DelayedActionType flags);
680 bool havePotentialSourceChild();
681 void noneSupported();
682 void cancelPendingEventsAndCallbacks();
683 void waitForSourceChange();
684 void prepareToPlay();
686 URL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction);
688 #if ENABLE(VIDEO_TRACK)
689 void updateActiveTextTrackCues(const MediaTime&);
690 HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
692 enum ReconfigureMode {
696 void markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMode);
697 void captionPreferencesChanged() override;
700 // These "internal" functions do not check user gesture restrictions.
703 void pauseInternal();
705 void prepareForLoad();
706 void allowVideoRendering();
708 bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
709 void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
710 void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
712 enum class UpdateState { Asynchronously, Synchronously };
714 void updatePlayState(UpdateState updateState = UpdateState::Synchronously);
716 void setPlaying(bool);
717 bool potentiallyPlaying() const;
718 bool endedPlayback() const;
719 bool stoppedDueToErrors() const;
720 bool pausedForUserInteraction() const;
721 bool couldPlayIfEnoughData() const;
722 SuccessOr<MediaPlaybackDenialReason> canTransitionFromAutoplayToPlay() const;
724 MediaTime minTimeSeekable() const;
725 MediaTime maxTimeSeekable() const;
727 // Pauses playback without changing any states or generating events
728 void setPausedInternal(bool);
730 void setPlaybackRateInternal(double);
732 void mediaCanStart(Document&) final;
734 void invalidateCachedTime() const;
735 void refreshCachedTime() const;
737 bool hasMediaControls() const;
738 bool createMediaControls();
739 void configureMediaControls();
741 void prepareMediaFragmentURI();
742 void applyMediaFragmentURI();
744 void changeNetworkStateFromLoadingToIdle();
746 void removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask = MediaElementSession::AllRestrictions);
748 void updateMediaController();
749 bool isBlocked() const;
750 bool isBlockedOnMediaController() const;
751 bool hasCurrentSrc() const override { return !m_currentSrc.isEmpty(); }
752 bool isLiveStream() const override { return movieLoadType() == MediaPlayerEnums::LiveStream; }
754 void updateSleepDisabling();
755 bool shouldDisableSleep() const;
757 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
758 void didAddUserAgentShadowRoot(ShadowRoot*) override;
759 DOMWrapperWorld& ensureIsolatedWorld();
760 bool ensureMediaControlsInjectedScript();
763 PlatformMediaSession::MediaType mediaType() const override;
764 PlatformMediaSession::MediaType presentationType() const override;
765 PlatformMediaSession::DisplayType displayType() const override;
766 PlatformMediaSession::CharacteristicsFlags characteristics() const final;
768 void suspendPlayback() override;
769 void resumeAutoplaying() override;
770 void mayResumePlayback(bool shouldResume) override;
771 String mediaSessionTitle() const override;
772 double mediaSessionDuration() const override { return duration(); }
773 double mediaSessionCurrentTime() const override { return currentTime(); }
774 bool canReceiveRemoteControlCommands() const override { return true; }
775 void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) override;
776 bool supportsSeeking() const override;
777 bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override;
778 bool shouldOverrideBackgroundLoadingRestriction() const override;
779 bool canProduceAudio() const final;
781 void pageMutedStateDidChange() override;
783 bool effectiveMuted() const;
785 void registerWithDocument(Document&);
786 void unregisterWithDocument(Document&);
788 void updateCaptionContainer();
789 void ensureMediaControlsShadowRoot();
791 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
792 void prepareForDocumentSuspension() final;
793 void resumeFromDocumentSuspension() final;
795 void updateMediaState(UpdateState updateState = UpdateState::Synchronously);
796 bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; }
799 bool isVideoTooSmallForInlinePlayback();
800 void isVisibleInViewportChanged() final;
801 void updateShouldAutoplay();
803 void pauseAfterDetachedTask();
804 void updatePlaybackControlsManager();
805 void scheduleUpdatePlaybackControlsManager();
806 void playbackControlsManagerBehaviorRestrictionsTimerFired();
808 void updateRenderer();
810 void updatePageScaleFactorJSProperty();
811 void updateUsesLTRUserInterfaceLayoutDirectionJSProperty();
812 void setControllerJSProperty(const char*, JSC::JSValue);
814 void addBehaviorRestrictionsOnEndIfNecessary();
815 void handleSeekToPlaybackPosition(double);
816 void seekToPlaybackPositionEndedTimerFired();
818 Timer m_pendingActionTimer;
819 Timer m_progressEventTimer;
820 Timer m_playbackProgressTimer;
822 Timer m_playbackControlsManagerBehaviorRestrictionsTimer;
823 Timer m_seekToPlaybackPositionEndedTimer;
824 GenericTaskQueue<Timer> m_seekTaskQueue;
825 GenericTaskQueue<Timer> m_resizeTaskQueue;
826 GenericTaskQueue<Timer> m_shadowDOMTaskQueue;
827 GenericTaskQueue<Timer> m_promiseTaskQueue;
828 GenericTaskQueue<Timer> m_pauseAfterDetachedTaskQueue;
829 GenericTaskQueue<Timer> m_updatePlaybackControlsManagerQueue;
830 GenericTaskQueue<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue;
831 RefPtr<TimeRanges> m_playedTimeRanges;
832 GenericEventQueue m_asyncEventQueue;
834 Vector<DOMPromise<void>> m_pendingPlayPromises;
836 double m_requestedPlaybackRate { 1 };
837 double m_reportedPlaybackRate { 1 };
838 double m_defaultPlaybackRate { 1 };
839 bool m_webkitPreservesPitch { true };
840 NetworkState m_networkState { NETWORK_EMPTY };
841 ReadyState m_readyState { HAVE_NOTHING };
842 ReadyState m_readyStateMaximum { HAVE_NOTHING };
845 RefPtr<MediaError> m_error;
848 PendingSeek(const MediaTime& now, const MediaTime& targetTime, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance)
850 , targetTime(targetTime)
851 , negativeTolerance(negativeTolerance)
852 , positiveTolerance(positiveTolerance)
856 MediaTime targetTime;
857 MediaTime negativeTolerance;
858 MediaTime positiveTolerance;
860 std::unique_ptr<PendingSeek> m_pendingSeek;
861 SeekType m_pendingSeekType { NoSeek };
863 double m_volume { 1 };
864 bool m_volumeInitialized { false };
865 MediaTime m_lastSeekTime;
867 double m_previousProgressTime { std::numeric_limits<double>::max() };
868 double m_playbackStartedTime { 0 };
870 // The last time a timeupdate event was sent (based on monotonic clock).
871 double m_clockTimeAtLastUpdateEvent { 0 };
873 // The last time a timeupdate event was sent in movie time.
874 MediaTime m_lastTimeUpdateEventMovieTime;
877 enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
878 LoadState m_loadState { WaitingForSource };
879 RefPtr<HTMLSourceElement> m_currentSourceNode;
880 RefPtr<Node> m_nextChildNodeToConsider;
882 VideoFullscreenMode m_videoFullscreenMode { VideoFullscreenModeNone };
883 bool m_preparedForInline;
884 std::function<void()> m_preparedForInlineCompletionHandler;
886 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
887 RetainPtr<PlatformLayer> m_videoFullscreenLayer;
888 FloatRect m_videoFullscreenFrame;
889 MediaPlayerEnums::VideoGravity m_videoFullscreenGravity { MediaPlayer::VideoGravityResizeAspect };
892 RefPtr<MediaPlayer> m_player;
894 MediaPlayerEnums::Preload m_preload { MediaPlayer::Auto };
896 DisplayMode m_displayMode { Unknown };
898 // Counter incremented while processing a callback from the media player, so we can avoid
899 // calling the media engine recursively.
900 int m_processingMediaPlayerCallback { 0 };
902 #if ENABLE(MEDIA_SESSION)
904 RefPtr<MediaSession> m_session;
905 bool m_shouldDuck { false };
906 uint64_t m_elementID;
909 #if ENABLE(MEDIA_SOURCE)
910 RefPtr<MediaSource> m_mediaSource;
911 unsigned m_droppedVideoFrames { 0 };
914 mutable MediaTime m_cachedTime;
915 mutable double m_clockTimeAtLastCachedTimeUpdate { 0 };
916 mutable double m_minimumClockTimeToUpdateCachedTime { 0 };
918 MediaTime m_fragmentStartTime;
919 MediaTime m_fragmentEndTime;
921 using PendingActionFlags = unsigned;
922 PendingActionFlags m_pendingActionFlags { 0 };
924 enum ActionAfterScanType { Nothing, Play, Pause };
925 ActionAfterScanType m_actionAfterScan { Nothing };
927 enum ScanType { Seek, Scan };
928 ScanType m_scanType { Scan };
929 ScanDirection m_scanDirection { Forward };
931 bool m_firstTimePlaying : 1;
933 bool m_isWaitingUntilMediaCanStart : 1;
934 bool m_shouldDelayLoadEvent : 1;
935 bool m_haveFiredLoadedData : 1;
936 bool m_inActiveDocument : 1;
937 bool m_autoplaying : 1;
939 bool m_explicitlyMuted : 1;
940 bool m_initiallyMuted : 1;
944 // data has not been loaded since sending a "stalled" event
945 bool m_sentStalledEvent : 1;
947 // time has not changed since sending an "ended" event
948 bool m_sentEndEvent : 1;
950 bool m_pausedInternal : 1;
952 // Not all media engines provide enough information about a file to be able to
953 // support progress events so setting m_sendProgressEvents disables them
954 bool m_sendProgressEvents : 1;
956 bool m_closedCaptionsVisible : 1;
957 bool m_webkitLegacyClosedCaptionOverride : 1;
958 bool m_completelyLoaded : 1;
959 bool m_havePreparedToPlay : 1;
960 bool m_parsingInProgress : 1;
961 bool m_elementIsHidden : 1;
962 bool m_creatingControls : 1;
963 bool m_receivedLayoutSizeChanged : 1;
964 bool m_hasEverNotifiedAboutPlaying : 1;
965 bool m_preventedFromPlayingWithoutUserGesture : 1;
967 bool m_hasEverHadAudio : 1;
968 bool m_hasEverHadVideo : 1;
970 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
971 bool m_mediaControlsDependOnPageScaleFactor : 1;
972 bool m_haveSetUpCaptionContainer : 1;
975 bool m_isScrubbingRemotely : 1;
977 #if ENABLE(VIDEO_TRACK)
978 bool m_tracksAreReady : 1;
979 bool m_haveVisibleTextTrack : 1;
980 bool m_processingPreferenceChange : 1;
982 String m_subtitleTrackLanguage;
983 MediaTime m_lastTextTrackUpdateTime { -1, 1 };
985 CaptionUserPreferences::CaptionDisplayMode m_captionDisplayMode { CaptionUserPreferences::Automatic };
987 RefPtr<AudioTrackList> m_audioTracks;
988 RefPtr<TextTrackList> m_textTracks;
989 RefPtr<VideoTrackList> m_videoTracks;
990 Vector<RefPtr<TextTrack>> m_textTracksWhenResourceSelectionBegan;
992 CueIntervalTree m_cueTree;
994 CueList m_currentlyActiveCues;
995 int m_ignoreTrackDisplayUpdate { 0 };
997 bool m_requireCaptionPreferencesChangedCallbacks { false };
1000 #if ENABLE(WEB_AUDIO)
1001 // This is a weak reference, since m_audioSourceNode holds a reference to us.
1002 // The value is set just after the MediaElementAudioSourceNode is created.
1003 // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode().
1004 MediaElementAudioSourceNode* m_audioSourceNode { nullptr };
1007 String m_mediaGroup;
1008 friend class MediaController;
1009 RefPtr<MediaController> m_mediaController;
1011 std::unique_ptr<DisplaySleepDisabler> m_sleepDisabler;
1013 friend class TrackDisplayUpdateScope;
1015 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
1016 RefPtr<WebKitMediaKeys> m_webKitMediaKeys;
1019 std::unique_ptr<MediaElementSession> m_mediaSession;
1020 size_t m_reportedExtraMemoryCost { 0 };
1022 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1023 friend class MediaControlsHost;
1024 RefPtr<MediaControlsHost> m_mediaControlsHost;
1025 RefPtr<DOMWrapperWorld> m_isolatedWorld;
1028 #if ENABLE(MEDIA_STREAM)
1029 RefPtr<MediaStream> m_mediaStreamSrcObject;
1030 bool m_settingMediaStreamSrcObject { false };
1033 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
1034 MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
1035 bool m_hasPlaybackTargetAvailabilityListeners { false };
1036 bool m_failedToPlayToWirelessTarget { false };
1037 bool m_isPlayingToWirelessTarget { false };
1041 #if ENABLE(VIDEO_TRACK) && !defined(NDEBUG)
1043 // Template specialization required by PodIntervalTree in debug mode.
1044 template <> struct ValueToString<TextTrackCue*> {
1045 static String string(TextTrackCue* const& cue)
1048 if (cue->isRenderable())
1049 text = toVTTCue(cue)->text();
1050 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());
1058 template<> struct ValueToString<MediaTime> {
1059 static String string(const MediaTime& time)
1061 return toString(time);
1067 } // namespace WebCore
1069 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLMediaElement)
1070 static bool isType(const WebCore::Element& element) { return element.isMediaElement(); }
1071 static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
1072 SPECIALIZE_TYPE_TRAITS_END()