2 * Copyright (C) 2007-2015 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 "HTMLElement.h"
31 #include "ActiveDOMObject.h"
32 #include "GenericEventQueue.h"
33 #include "GenericTaskQueue.h"
34 #include "HTMLMediaElementEnums.h"
35 #include "JSDOMPromise.h"
36 #include "MediaCanStartListener.h"
37 #include "MediaControllerInterface.h"
38 #include "MediaElementSession.h"
39 #include "MediaProducer.h"
40 #include "PageThrottler.h"
41 #include "UserInterfaceLayoutDirection.h"
43 #if ENABLE(VIDEO_TRACK)
44 #include "AudioTrack.h"
45 #include "CaptionUserPreferences.h"
46 #include "PODIntervalTree.h"
47 #include "TextTrack.h"
48 #include "TextTrackCue.h"
50 #include "VideoTrack.h"
54 #include <wtf/StringPrintStream.h>
59 class AudioSourceProvider;
61 class AudioTrackPrivate;
63 class DisplaySleepDisabler;
65 class HTMLSourceElement;
66 class HTMLTrackElement;
67 class InbandTextTrackPrivate;
68 class MediaController;
70 class MediaControlsHost;
71 class MediaElementAudioSourceNode;
79 class ScriptExecutionContext;
84 class VideoPlaybackQuality;
86 class VideoTrackPrivate;
88 #if ENABLE(VIDEO_TRACK)
89 typedef PODIntervalTree<MediaTime, TextTrackCue*> CueIntervalTree;
90 typedef CueIntervalTree::IntervalType CueInterval;
91 typedef Vector<CueInterval> CueList;
94 class HTMLMediaElement
96 , public ActiveDOMObject
97 , public MediaControllerInterface
98 , public MediaPlayerSupportsTypeClient
99 , public PlatformMediaSessionClient
100 , private MediaCanStartListener
101 , private MediaPlayerClient
102 , private MediaProducer
103 #if ENABLE(VIDEO_TRACK)
104 , private AudioTrackClient
105 , private TextTrackClient
106 , private VideoTrackClient
110 MediaPlayer* player() const { return m_player.get(); }
112 virtual bool isVideo() const { return false; }
113 bool hasVideo() const override { return false; }
114 bool hasAudio() const override;
116 static HashSet<HTMLMediaElement*>& allMediaElements();
118 void rewind(double timeDelta);
119 WEBCORE_EXPORT void returnToRealtime() override;
121 // Eventually overloaded in HTMLVideoElement
122 bool supportsFullscreen(HTMLMediaElementEnums::VideoFullscreenMode) const override { return false; };
124 bool supportsScanning() const override;
126 bool canSaveMediaData() const;
128 bool doesHaveAttribute(const AtomicString&, AtomicString* value = nullptr) const override;
130 WEBCORE_EXPORT PlatformMedia platformMedia() const;
131 PlatformLayer* platformLayer() const;
132 bool isVideoLayerInline();
133 void setPreparedToReturnVideoLayerToInline(bool);
134 void waitForPreparedForInlineThen(std::function<void()> completionHandler = [] { });
135 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
136 void setVideoFullscreenLayer(PlatformLayer*, std::function<void()> completionHandler = [] { });
137 PlatformLayer* videoFullscreenLayer() const { return m_videoFullscreenLayer.get(); }
138 void setVideoFullscreenFrame(FloatRect);
139 void setVideoFullscreenGravity(MediaPlayerEnums::VideoGravity);
140 MediaPlayerEnums::VideoGravity videoFullscreenGravity() const { return m_videoFullscreenGravity; }
143 using HTMLMediaElementEnums::DelayedActionType;
144 void scheduleDelayedAction(DelayedActionType);
145 void scheduleResolvePendingPlayPromises();
146 void rejectPendingPlayPromises(DOMError&);
147 void resolvePendingPlayPromises();
148 void scheduleNotifyAboutPlaying();
149 void notifyAboutPlaying();
151 MediaPlayerEnums::MovieLoadType movieLoadType() const;
153 bool inActiveDocument() const { return m_inActiveDocument; }
155 const Document* hostingDocument() const override { return &document(); }
159 MediaError* error() const;
161 void setSrc(const String&);
162 const URL& currentSrc() const { return m_currentSrc; }
164 #if ENABLE(MEDIA_STREAM)
165 MediaStream* srcObject() const { return m_mediaStreamSrcObject.get(); }
166 void setSrcObject(ScriptExecutionContext&, MediaStream*);
169 void setCrossOrigin(const AtomicString&);
170 String crossOrigin() const;
173 using HTMLMediaElementEnums::NetworkState;
174 NetworkState networkState() const;
176 String preload() const;
177 void setPreload(const String&);
179 Ref<TimeRanges> buffered() const override;
181 String canPlayType(const String& mimeType, const String& keySystem = String(), const URL& = URL()) const;
184 using HTMLMediaElementEnums::ReadyState;
185 ReadyState readyState() const override;
186 bool seeking() const;
189 WEBCORE_EXPORT double currentTime() const override;
190 void setCurrentTime(double) override;
191 virtual void setCurrentTime(double, ExceptionCode&);
192 virtual double getStartDate() const;
193 WEBCORE_EXPORT double duration() const override;
194 WEBCORE_EXPORT bool paused() const override;
195 double defaultPlaybackRate() const override;
196 void setDefaultPlaybackRate(double) override;
197 WEBCORE_EXPORT double playbackRate() const override;
198 void setPlaybackRate(double) override;
200 // MediaTime versions of playback state
201 MediaTime currentMediaTime() const;
202 void setCurrentTime(const MediaTime&);
203 MediaTime durationMediaTime() const;
204 void fastSeek(const MediaTime&);
206 void updatePlaybackRate();
207 bool webkitPreservesPitch() const;
208 void setWebkitPreservesPitch(bool);
209 Ref<TimeRanges> played() override;
210 Ref<TimeRanges> seekable() const override;
211 WEBCORE_EXPORT bool ended() const;
212 bool autoplay() const;
213 bool isAutoplaying() const { return m_autoplaying; }
215 void setLoop(bool b);
217 typedef DOMPromise<std::nullptr_t> PlayPromise;
218 void play(PlayPromise&&);
220 WEBCORE_EXPORT void play() override;
221 WEBCORE_EXPORT void pause() override;
222 void setShouldBufferData(bool) override;
223 void fastSeek(double);
224 double minFastReverseRate() const;
225 double maxFastForwardRate() const;
227 void purgeBufferedDataIfPossible();
230 bool webkitHasClosedCaptions() const;
231 bool webkitClosedCaptionsVisible() const;
232 void setWebkitClosedCaptionsVisible(bool);
234 bool elementIsHidden() const override { return m_elementIsHidden; }
236 #if ENABLE(MEDIA_STATISTICS)
238 unsigned webkitAudioDecodedByteCount() const;
239 unsigned webkitVideoDecodedByteCount() const;
242 #if ENABLE(MEDIA_SOURCE)
244 void closeMediaSource();
245 void incrementDroppedFrameCount() { ++m_droppedVideoFrames; }
246 size_t maximumSourceBufferSize(const SourceBuffer&) const;
249 #if ENABLE(ENCRYPTED_MEDIA)
250 void webkitGenerateKeyRequest(const String& keySystem, const RefPtr<Uint8Array>& initData, ExceptionCode&);
251 void webkitAddKey(const String& keySystem, Uint8Array& key, const RefPtr<Uint8Array>& initData, const String& sessionId, ExceptionCode&);
252 void webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionCode&);
255 #if ENABLE(ENCRYPTED_MEDIA_V2)
256 MediaKeys* keys() const { return m_mediaKeys.get(); }
257 void setMediaKeys(MediaKeys*);
263 bool controls() const;
264 void setControls(bool);
265 WEBCORE_EXPORT double volume() const override;
266 void setVolume(double, ExceptionCode&) override;
267 WEBCORE_EXPORT bool muted() const override;
268 WEBCORE_EXPORT void setMuted(bool) override;
270 WEBCORE_EXPORT void togglePlayState();
271 WEBCORE_EXPORT void beginScrubbing() override;
272 WEBCORE_EXPORT void endScrubbing() override;
274 void beginScanning(ScanDirection) override;
275 void endScanning() override;
276 double nextScanRate();
278 WEBCORE_EXPORT bool canPlay() const override;
280 double percentLoaded() const;
282 #if ENABLE(VIDEO_TRACK)
283 RefPtr<TextTrack> addTextTrack(const String& kind, const String& label, const String& language, ExceptionCode&);
285 AudioTrackList& audioTracks();
286 TextTrackList& textTracks();
287 VideoTrackList& videoTracks();
289 CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
291 void addAudioTrack(Ref<AudioTrack>&&);
292 void addTextTrack(Ref<TextTrack>&&);
293 void addVideoTrack(Ref<VideoTrack>&&);
294 void removeAudioTrack(AudioTrack&);
295 void removeTextTrack(TextTrack&, bool scheduleEvent = true);
296 void removeVideoTrack(VideoTrack&);
297 void forgetResourceSpecificTracks();
298 void closeCaptionTracksChanged();
299 void notifyMediaPlayerOfTextTrackChanges();
301 virtual void didAddTextTrack(HTMLTrackElement*);
302 virtual void didRemoveTextTrack(HTMLTrackElement*);
304 void mediaPlayerDidAddAudioTrack(PassRefPtr<AudioTrackPrivate>) override;
305 void mediaPlayerDidAddTextTrack(PassRefPtr<InbandTextTrackPrivate>) override;
306 void mediaPlayerDidAddVideoTrack(PassRefPtr<VideoTrackPrivate>) override;
307 void mediaPlayerDidRemoveAudioTrack(PassRefPtr<AudioTrackPrivate>) override;
308 void mediaPlayerDidRemoveTextTrack(PassRefPtr<InbandTextTrackPrivate>) override;
309 void mediaPlayerDidRemoveVideoTrack(PassRefPtr<VideoTrackPrivate>) override;
311 #if ENABLE(AVF_CAPTIONS)
312 Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources() override;
316 void configureTextTrackGroupForLanguage(const TrackGroup&) const;
317 void configureTextTracks();
318 void configureTextTrackGroup(const TrackGroup&);
320 void setSelectedTextTrack(TextTrack*);
322 bool textTracksAreReady() const;
323 using HTMLMediaElementEnums::TextTrackVisibilityCheckType;
324 void configureTextTrackDisplay(TextTrackVisibilityCheckType checkType = CheckTextTrackVisibility);
325 void updateTextTrackDisplay();
328 void audioTrackEnabledChanged(AudioTrack*) override;
331 virtual void textTrackReadyStateChanged(TextTrack*);
332 void textTrackKindChanged(TextTrack*) override;
333 void textTrackModeChanged(TextTrack*) override;
334 void textTrackAddCues(TextTrack*, const TextTrackCueList*) override;
335 void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) override;
336 void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) override;
337 void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) override;
340 void videoTrackSelectedChanged(VideoTrack*) override;
342 bool requiresTextTrackRepresentation() const;
343 void setTextTrackRepresentation(TextTrackRepresentation*);
344 void syncTextTrackBounds();
347 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
348 void webkitShowPlaybackTargetPicker();
349 bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
350 bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
352 void wirelessRoutesAvailableDidChange() override;
353 bool canPlayToWirelessPlaybackTarget() const override;
354 bool isPlayingToWirelessPlaybackTarget() const override;
355 void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
356 void setShouldPlayToPlaybackTarget(bool) override;
358 bool webkitCurrentPlaybackTargetIsWireless() const;
360 // EventTarget function.
361 // Both Node (via HTMLElement) and ActiveDOMObject define this method, which
362 // causes an ambiguity error at compile time. This class's constructor
363 // ensures that both implementations return document, so return the result
364 // of one of them here.
365 using HTMLElement::scriptExecutionContext;
367 bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
369 WEBCORE_EXPORT bool isFullscreen() const override;
370 bool isStandardFullscreen() const;
371 void toggleStandardFullscreenState();
373 using MediaPlayerEnums::VideoFullscreenMode;
374 VideoFullscreenMode fullscreenMode() const { return m_videoFullscreenMode; }
375 virtual void fullscreenModeChanged(VideoFullscreenMode);
377 void enterFullscreen(VideoFullscreenMode);
378 void enterFullscreen() override;
379 WEBCORE_EXPORT void exitFullscreen();
381 bool hasClosedCaptions() const override;
382 bool closedCaptionsVisible() const override;
383 void setClosedCaptionsVisible(bool) override;
385 MediaControls* mediaControls() const;
387 void sourceWasRemoved(HTMLSourceElement*);
388 void sourceWasAdded(HTMLSourceElement*);
390 void privateBrowsingStateDidChange() override;
392 // Media cache management.
393 WEBCORE_EXPORT static void setMediaCacheDirectory(const String&);
394 WEBCORE_EXPORT static const String& mediaCacheDirectory();
395 WEBCORE_EXPORT static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&);
396 WEBCORE_EXPORT static void clearMediaCache(const String&, std::chrono::system_clock::time_point modifiedSince = { });
397 WEBCORE_EXPORT static void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&);
398 static void resetMediaEngines();
400 bool isPlaying() const { return m_playing; }
402 bool hasPendingActivity() const override;
404 #if ENABLE(WEB_AUDIO)
405 MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; }
406 void setAudioSourceNode(MediaElementAudioSourceNode*);
408 AudioSourceProvider* audioSourceProvider();
411 using HTMLMediaElementEnums::InvalidURLAction;
412 bool isSafeToLoadURL(const URL&, InvalidURLAction);
414 const String& mediaGroup() const;
415 void setMediaGroup(const String&);
417 MediaController* controller() const;
418 void setController(PassRefPtr<MediaController>);
420 void enteredOrExitedFullscreen() { configureMediaControls(); }
422 unsigned long long fileSize() const;
424 void mediaLoadingFailed(MediaPlayerEnums::NetworkState);
425 void mediaLoadingFailedFatally(MediaPlayerEnums::NetworkState);
427 #if ENABLE(MEDIA_SESSION)
428 WEBCORE_EXPORT double playerVolume() const;
430 const String& kind() const { return m_kind; }
431 void setKind(const String& kind) { m_kind = kind; }
433 MediaSession* session() const;
434 void setSession(MediaSession*);
436 void setShouldDuck(bool);
438 static HTMLMediaElement* elementWithID(uint64_t);
439 uint64_t elementID() const { return m_elementID; }
442 #if ENABLE(MEDIA_SOURCE)
443 RefPtr<VideoPlaybackQuality> getVideoPlaybackQuality();
446 MediaPlayerEnums::Preload preloadValue() const { return m_preload; }
447 MediaElementSession& mediaSession() const { return *m_mediaSession; }
449 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
450 void pageScaleFactorChanged();
451 void userInterfaceLayoutDirectionChanged();
452 WEBCORE_EXPORT String getCurrentMediaControlsStatus();
455 MediaControlsHost* mediaControlsHost() { return m_mediaControlsHost.get(); }
457 bool isDisablingSleep() const { return m_sleepDisabler.get(); }
459 double maxBufferedTime() const;
461 MediaProducer::MediaStateFlags mediaState() const override;
463 void layoutSizeChanged();
464 void visibilityDidChange();
466 void allowsMediaDocumentInlinePlaybackChanged();
467 void updateShouldPlay();
469 RenderMedia* renderer() const;
472 HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser);
473 virtual ~HTMLMediaElement();
475 void parseAttribute(const QualifiedName&, const AtomicString&) override;
476 void finishParsingChildren() override;
477 bool isURLAttribute(const Attribute&) const override;
478 void willAttachRenderers() override;
479 void didAttachRenderers() override;
480 void willDetachRenderers() override;
481 void didDetachRenderers() override;
483 void didMoveToNewDocument(Document* oldDocument) override;
485 enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
486 DisplayMode displayMode() const { return m_displayMode; }
487 virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
489 bool isMediaElement() const final { return true; }
491 #if ENABLE(VIDEO_TRACK)
492 bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0 || !m_textTracks || !m_cueTree.size(); }
493 void beginIgnoringTrackDisplayUpdateRequests();
494 void endIgnoringTrackDisplayUpdateRequests();
497 RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
499 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
500 bool mediaControlsDependOnPageScaleFactor() const { return m_mediaControlsDependOnPageScaleFactor; }
501 void setMediaControlsDependOnPageScaleFactor(bool);
502 void updateMediaControlsAfterPresentationModeChange();
505 void scheduleEvent(const AtomicString& eventName);
508 void createMediaPlayer();
510 bool alwaysCreateUserAgentShadowRoot() const override { return true; }
512 bool supportsFocus() const override;
513 bool isMouseFocusable() const override;
514 bool rendererIsNeeded(const RenderStyle&) override;
515 bool childShouldCreateRenderer(const Node&) const override;
516 InsertionNotificationRequest insertedInto(ContainerNode&) override;
517 void removedFrom(ContainerNode&) override;
518 void didRecalcStyle(Style::Change) override;
520 void willBecomeFullscreenElement() override;
521 void didBecomeFullscreenElement() override;
522 void willStopBeingFullscreenElement() override;
524 // ActiveDOMObject API.
525 const char* activeDOMObjectName() const override;
526 bool canSuspendForDocumentSuspension() const override;
527 void suspend(ReasonForSuspension) override;
528 void resume() override;
529 void stop() override;
530 void stopWithoutDestroyingMediaPlayer();
531 void contextDestroyed() override;
533 void mediaVolumeDidChange() override;
535 void visibilityStateChanged() override;
537 virtual void updateDisplayState() { }
539 void setReadyState(MediaPlayerEnums::ReadyState);
540 void setNetworkState(MediaPlayerEnums::NetworkState);
542 double effectivePlaybackRate() const;
543 double requestedPlaybackRate() const;
545 void mediaPlayerNetworkStateChanged(MediaPlayer*) override;
546 void mediaPlayerReadyStateChanged(MediaPlayer*) override;
547 void mediaPlayerTimeChanged(MediaPlayer*) override;
548 void mediaPlayerVolumeChanged(MediaPlayer*) override;
549 void mediaPlayerMuteChanged(MediaPlayer*) override;
550 void mediaPlayerDurationChanged(MediaPlayer*) override;
551 void mediaPlayerRateChanged(MediaPlayer*) override;
552 void mediaPlayerPlaybackStateChanged(MediaPlayer*) override;
553 void mediaPlayerSawUnsupportedTracks(MediaPlayer*) override;
554 void mediaPlayerResourceNotSupported(MediaPlayer*) override;
555 void mediaPlayerRepaint(MediaPlayer*) override;
556 void mediaPlayerSizeChanged(MediaPlayer*) override;
557 bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) override;
558 void mediaPlayerRenderingModeChanged(MediaPlayer*) override;
559 void mediaPlayerEngineUpdated(MediaPlayer*) override;
560 void mediaEngineWasUpdated();
562 void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) override;
563 void mediaPlayerCharacteristicChanged(MediaPlayer*) override;
565 #if ENABLE(ENCRYPTED_MEDIA)
566 void mediaPlayerKeyAdded(MediaPlayer*, const String& keySystem, const String& sessionId) override;
567 void mediaPlayerKeyError(MediaPlayer*, const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode) override;
568 void mediaPlayerKeyMessage(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const URL& defaultURL) override;
569 bool mediaPlayerKeyNeeded(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength) override;
572 #if ENABLE(ENCRYPTED_MEDIA_V2)
573 RefPtr<ArrayBuffer> mediaPlayerCachedKeyForKeyId(const String& keyId) const override;
574 bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override;
575 String mediaPlayerMediaKeysStorageDirectory() const override;
578 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
579 void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override;
580 void enqueuePlaybackTargetAvailabilityChangedEvent();
582 using EventTarget::dispatchEvent;
583 bool dispatchEvent(Event&) override;
586 #if ENABLE(MEDIA_SESSION)
587 void setSessionInternal(MediaSession&);
590 String mediaPlayerReferrer() const override;
591 String mediaPlayerUserAgent() const override;
593 bool mediaPlayerNeedsSiteSpecificHacks() const override;
594 String mediaPlayerDocumentHost() const override;
596 void mediaPlayerEnterFullscreen() override;
597 void mediaPlayerExitFullscreen() override;
598 bool mediaPlayerIsFullscreen() const override;
599 bool mediaPlayerIsFullscreenPermitted() const override;
600 bool mediaPlayerIsVideo() const override;
601 LayoutRect mediaPlayerContentBoxRect() const override;
602 float mediaPlayerContentsScale() const override;
603 void mediaPlayerSetSize(const IntSize&) override;
604 void mediaPlayerPause() override;
605 void mediaPlayerPlay() override;
606 bool mediaPlayerPlatformVolumeConfigurationRequired() const override;
607 bool mediaPlayerIsPaused() const override;
608 bool mediaPlayerIsLooping() const override;
609 CachedResourceLoader* mediaPlayerCachedResourceLoader() override;
610 RefPtr<PlatformMediaResourceLoader> mediaPlayerCreateResourceLoader() override;
611 bool mediaPlayerShouldUsePersistentCache() const override;
612 const String& mediaPlayerMediaCacheDirectory() const override;
614 #if PLATFORM(WIN) && USE(AVFOUNDATION)
615 GraphicsDeviceAdapter* mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const override;
618 bool mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge&) override;
619 void mediaPlayerHandlePlaybackCommand(PlatformMediaSession::RemoteControlCommandType command) override { didReceiveRemoteControlCommand(command, nullptr); }
620 String mediaPlayerSourceApplicationIdentifier() const override;
621 Vector<String> mediaPlayerPreferredAudioCharacteristics() const override;
624 String mediaPlayerNetworkInterfaceName() const override;
625 bool mediaPlayerGetRawCookies(const URL&, Vector<Cookie>&) const override;
628 bool mediaPlayerIsInMediaDocument() const final;
629 void mediaPlayerEngineFailedToLoad() const final;
631 double mediaPlayerRequestedPlaybackRate() const final;
632 VideoFullscreenMode mediaPlayerFullscreenMode() const final { return fullscreenMode(); }
635 void requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback&) final;
638 void pendingActionTimerFired();
639 void progressEventTimerFired();
640 void playbackProgressTimerFired();
641 void scanTimerFired();
643 void startPlaybackProgressTimer();
644 void startProgressEventTimer();
645 void stopPeriodicTimers();
647 void seek(const MediaTime&);
648 void seekInternal(const MediaTime&);
649 void seekWithTolerance(const MediaTime&, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance, bool fromDOM);
652 void addPlayedRange(const MediaTime& start, const MediaTime& end);
654 void scheduleTimeupdateEvent(bool periodicEvent);
655 virtual void scheduleResizeEvent() { }
656 virtual void scheduleResizeEventIfSizeChanged() { }
658 void selectMediaResource();
659 void loadResource(const URL&, ContentType&, const String& keySystem);
660 void scheduleNextSourceChild();
661 void loadNextSourceChild();
662 void userCancelledLoad();
663 void clearMediaPlayer(DelayedActionType flags);
664 bool havePotentialSourceChild();
665 void noneSupported();
666 void cancelPendingEventsAndCallbacks();
667 void waitForSourceChange();
668 void prepareToPlay();
670 URL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction);
672 #if ENABLE(VIDEO_TRACK)
673 void updateActiveTextTrackCues(const MediaTime&);
674 HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
676 enum ReconfigureMode {
680 void markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMode);
681 void captionPreferencesChanged() override;
684 // These "internal" functions do not check user gesture restrictions.
687 void pauseInternal();
689 void prepareForLoad();
690 void allowVideoRendering();
692 bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
693 void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
694 void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
696 enum class UpdateState { Asynchronously, Synchronously };
698 void updatePlayState(UpdateState updateState = UpdateState::Synchronously);
700 void setPlaying(bool);
701 bool potentiallyPlaying() const;
702 bool endedPlayback() const;
703 bool stoppedDueToErrors() const;
704 bool pausedForUserInteraction() const;
705 bool couldPlayIfEnoughData() const;
706 bool canTransitionFromAutoplayToPlay() const;
708 MediaTime minTimeSeekable() const;
709 MediaTime maxTimeSeekable() const;
711 // Pauses playback without changing any states or generating events
712 void setPausedInternal(bool);
714 void setPlaybackRateInternal(double);
716 void mediaCanStart() override;
718 void setShouldDelayLoadEvent(bool);
719 void invalidateCachedTime() const;
720 void refreshCachedTime() const;
722 bool hasMediaControls() const;
723 bool createMediaControls();
724 void configureMediaControls();
726 void prepareMediaFragmentURI();
727 void applyMediaFragmentURI();
729 void changeNetworkStateFromLoadingToIdle();
731 void removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask = MediaElementSession::AllRestrictions);
733 void updateMediaController();
734 bool isBlocked() const;
735 bool isBlockedOnMediaController() const;
736 bool hasCurrentSrc() const override { return !m_currentSrc.isEmpty(); }
737 bool isLiveStream() const override { return movieLoadType() == MediaPlayerEnums::LiveStream; }
739 void updateSleepDisabling();
740 bool shouldDisableSleep() const;
742 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
743 void didAddUserAgentShadowRoot(ShadowRoot*) override;
744 DOMWrapperWorld& ensureIsolatedWorld();
745 bool ensureMediaControlsInjectedScript();
748 PlatformMediaSession::MediaType mediaType() const override;
749 PlatformMediaSession::MediaType presentationType() const override;
750 PlatformMediaSession::DisplayType displayType() const override;
751 PlatformMediaSession::CharacteristicsFlags characteristics() const final;
753 void suspendPlayback() override;
754 void resumeAutoplaying() override;
755 void mayResumePlayback(bool shouldResume) override;
756 String mediaSessionTitle() const override;
757 double mediaSessionDuration() const override { return duration(); }
758 double mediaSessionCurrentTime() const override { return currentTime(); }
759 bool canReceiveRemoteControlCommands() const override { return true; }
760 void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) override;
761 bool supportsSeeking() const override;
762 bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override;
763 bool shouldOverrideBackgroundLoadingRestriction() const override;
765 void pageMutedStateDidChange() override;
767 bool effectiveMuted() const;
769 void registerWithDocument(Document&);
770 void unregisterWithDocument(Document&);
772 void updateCaptionContainer();
773 void ensureMediaControlsShadowRoot();
775 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
776 void prepareForDocumentSuspension() final;
777 void resumeFromDocumentSuspension() final;
779 void updateMediaState(UpdateState updateState = UpdateState::Synchronously);
780 bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; }
783 bool isVideoTooSmallForInlinePlayback();
784 void isVisibleInViewportChanged() final;
785 void updateShouldAutoplay();
787 void pauseAfterDetachedTask();
788 void updatePlaybackControlsManager();
789 void scheduleUpdatePlaybackControlsManager();
791 void updateRenderer();
793 void updatePageScaleFactorJSProperty();
794 void updateUsesLTRUserInterfaceLayoutDirectionJSProperty();
795 void setControllerJSProperty(const char*, JSC::JSValue);
797 Timer m_pendingActionTimer;
798 Timer m_progressEventTimer;
799 Timer m_playbackProgressTimer;
801 GenericTaskQueue<Timer> m_seekTaskQueue;
802 GenericTaskQueue<Timer> m_resizeTaskQueue;
803 GenericTaskQueue<Timer> m_shadowDOMTaskQueue;
804 GenericTaskQueue<Timer> m_promiseTaskQueue;
805 GenericTaskQueue<Timer> m_pauseAfterDetachedTaskQueue;
806 GenericTaskQueue<Timer> m_updatePlaybackControlsManagerQueue;
807 RefPtr<TimeRanges> m_playedTimeRanges;
808 GenericEventQueue m_asyncEventQueue;
810 Vector<PlayPromise> m_pendingPlayPromises;
812 double m_requestedPlaybackRate;
813 double m_reportedPlaybackRate;
814 double m_defaultPlaybackRate;
815 bool m_webkitPreservesPitch;
816 NetworkState m_networkState;
817 ReadyState m_readyState;
818 ReadyState m_readyStateMaximum;
821 RefPtr<MediaError> m_error;
824 PendingSeek(const MediaTime& now, const MediaTime& targetTime, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance)
826 , targetTime(targetTime)
827 , negativeTolerance(negativeTolerance)
828 , positiveTolerance(positiveTolerance)
832 MediaTime targetTime;
833 MediaTime negativeTolerance;
834 MediaTime positiveTolerance;
836 std::unique_ptr<PendingSeek> m_pendingSeek;
837 SeekType m_pendingSeekType { NoSeek };
840 bool m_volumeInitialized;
841 MediaTime m_lastSeekTime;
843 double m_previousProgressTime;
845 // The last time a timeupdate event was sent (based on monotonic clock).
846 double m_clockTimeAtLastUpdateEvent;
848 // The last time a timeupdate event was sent in movie time.
849 MediaTime m_lastTimeUpdateEventMovieTime;
852 enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
853 LoadState m_loadState;
854 RefPtr<HTMLSourceElement> m_currentSourceNode;
855 RefPtr<Node> m_nextChildNodeToConsider;
857 VideoFullscreenMode m_videoFullscreenMode;
858 bool m_preparedForInline;
859 std::function<void()> m_preparedForInlineCompletionHandler;
861 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
862 RetainPtr<PlatformLayer> m_videoFullscreenLayer;
863 FloatRect m_videoFullscreenFrame;
864 MediaPlayerEnums::VideoGravity m_videoFullscreenGravity;
867 std::unique_ptr<MediaPlayer> m_player;
869 MediaPlayerEnums::Preload m_preload;
871 DisplayMode m_displayMode;
873 // Counter incremented while processing a callback from the media player, so we can avoid
874 // calling the media engine recursively.
875 int m_processingMediaPlayerCallback;
877 #if ENABLE(MEDIA_SESSION)
879 RefPtr<MediaSession> m_session;
880 bool m_shouldDuck { false };
881 uint64_t m_elementID;
884 #if ENABLE(MEDIA_SOURCE)
885 RefPtr<MediaSource> m_mediaSource;
886 unsigned long m_droppedVideoFrames;
889 mutable MediaTime m_cachedTime;
890 mutable double m_clockTimeAtLastCachedTimeUpdate;
891 mutable double m_minimumClockTimeToUpdateCachedTime;
893 MediaTime m_fragmentStartTime;
894 MediaTime m_fragmentEndTime;
896 typedef unsigned PendingActionFlags;
897 PendingActionFlags m_pendingActionFlags;
899 enum ActionAfterScanType {
902 ActionAfterScanType m_actionAfterScan;
904 enum ScanType { Seek, Scan };
906 ScanDirection m_scanDirection;
908 bool m_firstTimePlaying : 1;
910 bool m_isWaitingUntilMediaCanStart : 1;
911 bool m_shouldDelayLoadEvent : 1;
912 bool m_haveFiredLoadedData : 1;
913 bool m_inActiveDocument : 1;
914 bool m_autoplaying : 1;
916 bool m_explicitlyMuted : 1;
917 bool m_initiallyMuted : 1;
921 // data has not been loaded since sending a "stalled" event
922 bool m_sentStalledEvent : 1;
924 // time has not changed since sending an "ended" event
925 bool m_sentEndEvent : 1;
927 bool m_pausedInternal : 1;
929 // Not all media engines provide enough information about a file to be able to
930 // support progress events so setting m_sendProgressEvents disables them
931 bool m_sendProgressEvents : 1;
933 bool m_closedCaptionsVisible : 1;
934 bool m_webkitLegacyClosedCaptionOverride : 1;
935 bool m_completelyLoaded : 1;
936 bool m_havePreparedToPlay : 1;
937 bool m_parsingInProgress : 1;
938 bool m_elementIsHidden : 1;
939 bool m_creatingControls : 1;
940 bool m_receivedLayoutSizeChanged : 1;
942 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
943 bool m_mediaControlsDependOnPageScaleFactor : 1;
944 bool m_haveSetUpCaptionContainer : 1;
947 #if ENABLE(VIDEO_TRACK)
948 bool m_tracksAreReady : 1;
949 bool m_haveVisibleTextTrack : 1;
950 bool m_processingPreferenceChange : 1;
952 String m_subtitleTrackLanguage;
953 MediaTime m_lastTextTrackUpdateTime;
955 CaptionUserPreferences::CaptionDisplayMode m_captionDisplayMode;
957 RefPtr<AudioTrackList> m_audioTracks;
958 RefPtr<TextTrackList> m_textTracks;
959 RefPtr<VideoTrackList> m_videoTracks;
960 Vector<RefPtr<TextTrack>> m_textTracksWhenResourceSelectionBegan;
962 CueIntervalTree m_cueTree;
964 CueList m_currentlyActiveCues;
965 int m_ignoreTrackDisplayUpdate;
967 bool m_requireCaptionPreferencesChangedCallbacks { false };
970 #if ENABLE(WEB_AUDIO)
971 // This is a weak reference, since m_audioSourceNode holds a reference to us.
972 // The value is set just after the MediaElementAudioSourceNode is created.
973 // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode().
974 MediaElementAudioSourceNode* m_audioSourceNode;
978 friend class MediaController;
979 RefPtr<MediaController> m_mediaController;
981 std::unique_ptr<DisplaySleepDisabler> m_sleepDisabler;
983 friend class TrackDisplayUpdateScope;
985 #if ENABLE(ENCRYPTED_MEDIA_V2)
986 RefPtr<MediaKeys> m_mediaKeys;
989 std::unique_ptr<MediaElementSession> m_mediaSession;
990 PageActivityAssertionToken m_activityToken;
991 size_t m_reportedExtraMemoryCost;
993 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
994 friend class MediaControlsHost;
995 RefPtr<MediaControlsHost> m_mediaControlsHost;
996 RefPtr<DOMWrapperWorld> m_isolatedWorld;
999 #if ENABLE(MEDIA_STREAM)
1000 RefPtr<MediaStream> m_mediaStreamSrcObject;
1003 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
1004 MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
1005 bool m_hasPlaybackTargetAvailabilityListeners { false };
1006 bool m_failedToPlayToWirelessTarget { false };
1007 bool m_isPlayingToWirelessTarget { false };
1011 #if ENABLE(VIDEO_TRACK)
1013 // Template specialization required by PodIntervalTree in debug mode.
1015 struct ValueToString<TextTrackCue*> {
1016 static String string(TextTrackCue* const& cue)
1019 if (cue->isRenderable())
1020 text = toVTTCue(cue)->text();
1021 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());
1029 struct ValueToString<MediaTime> {
1030 static String string(const MediaTime& time)
1032 return toString(time);
1037 } // namespace WebCore
1039 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLMediaElement)
1040 static bool isType(const WebCore::Element& element) { return element.isMediaElement(); }
1041 static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
1042 SPECIALIZE_TYPE_TRAITS_END()