Title: [217948] trunk/Source
Revision
217948
Author
[email protected]
Date
2017-06-08 14:47:39 -0700 (Thu, 08 Jun 2017)

Log Message

Implement additional AVPlayerController interfaces for minTime and maxTime.
https://bugs.webkit.org/show_bug.cgi?id=172396
rdar://problem/30737452

Patch by Jeremy Jones <[email protected]> on 2017-06-08
Reviewed by Jer Noble.

Source/WebCore:

No new tests because no change to DOM.

Add support for new HLS UI in AVKit.

This adds new properties (seekableTimeRangesLastModifiedTime, liveUpdateInterval, minTiming, maxTiming) to WebAVPlayerController.
Plumb these properties from AVPlayer up to AVKit.

Switch WebPlaybackSessionModelMediaElement from updating seekableRangesChanged using timeupdate event to using progress event.

Enable progress events on iOS.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement):
(WebCore::HTMLMediaElement::loadResource):
(WebCore::HTMLMediaElement::seekableTimeRangesLastModifiedTime):
(WebCore::HTMLMediaElement::liveUpdateInterval):
* html/HTMLMediaElement.h:
* platform/cf/CoreMediaSoftLink.cpp:
* platform/cf/CoreMediaSoftLink.h:
* platform/cocoa/WebPlaybackSessionModel.h:
(WebCore::WebPlaybackSessionModelClient::seekableRangesChanged):
* platform/cocoa/WebPlaybackSessionModelMediaElement.h:
* platform/cocoa/WebPlaybackSessionModelMediaElement.mm:
(WebCore::WebPlaybackSessionModelMediaElement::updateForEventName):
(WebCore::WebPlaybackSessionModelMediaElement::observedEventNames):
(WebCore::WebPlaybackSessionModelMediaElement::seekableTimeRangesLastModifiedTime):
(WebCore::WebPlaybackSessionModelMediaElement::liveUpdateInterval):
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::seekableTimeRangesLastModifiedTime):
(WebCore::MediaPlayer::liveUpdateInterval):
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::seekableTimeRangesLastModifiedTime):
(WebCore::MediaPlayerPrivateInterface::liveUpdateInterval):
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::seekableTimeRangesLastModifiedTime):
(WebCore::MediaPlayerPrivateAVFoundationObjC::liveUpdateInterval):
* platform/ios/WebAVPlayerController.h:
* platform/ios/WebAVPlayerController.mm:
(-[WebAVPlayerController init]):
(-[WebAVPlayerController dealloc]):
(-[WebAVPlayerController observeValueForKeyPath:ofObject:change:context:]):
(-[WebAVPlayerController updateMinMaxTiming]):
(-[WebAVPlayerController hasSeekableLiveStreamingContent]):
(+[WebAVPlayerController keyPathsForValuesAffectingHasSeekableLiveStreamingContent]):
(-[WebAVPlayerController resetMediaState]):
* platform/ios/WebPlaybackSessionInterfaceAVKit.h:
* platform/ios/WebPlaybackSessionInterfaceAVKit.mm:
(WebCore::WebPlaybackSessionInterfaceAVKit::WebPlaybackSessionInterfaceAVKit):
(WebCore::WebPlaybackSessionInterfaceAVKit::resetMediaState):
(WebCore::WebPlaybackSessionInterfaceAVKit::seekableRangesChanged):
* platform/ios/WebVideoFullscreenControllerAVKit.mm:
(WebVideoFullscreenControllerContext::seekableRangesChanged):
(WebVideoFullscreenControllerContext::seekableTimeRangesLastModifiedTime):
(WebVideoFullscreenControllerContext::liveUpdateInterval):
* platform/mac/WebPlaybackSessionInterfaceMac.h:
* platform/mac/WebPlaybackSessionInterfaceMac.mm:
(WebCore::WebPlaybackSessionInterfaceMac::seekableRangesChanged):
* platform/spi/cocoa/AVKitSPI.h:
* platform/spi/mac/AVFoundationSPI.h:

Source/WebKit2:

Add support for new HLS UI in AVKit.

Plumb seekableTimeRangesLastModifiedTime and liveUpdateInterval across process boundaries.

* UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h:
* UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in:
* UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm:
(WebKit::WebPlaybackSessionModelContext::setSeekableRanges):
(WebKit::WebPlaybackSessionManagerProxy::setSeekableRangesVector):
* WebProcess/cocoa/WebPlaybackSessionManager.h:
* WebProcess/cocoa/WebPlaybackSessionManager.mm:
(WebKit::WebPlaybackSessionInterfaceContext::seekableRangesChanged):
(WebKit::WebPlaybackSessionManager::seekableRangesChanged):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (217947 => 217948)


--- trunk/Source/WebCore/ChangeLog	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/ChangeLog	2017-06-08 21:47:39 UTC (rev 217948)
@@ -1,3 +1,73 @@
+2017-06-08  Jeremy Jones  <[email protected]>
+
+        Implement additional AVPlayerController interfaces for minTime and maxTime.
+        https://bugs.webkit.org/show_bug.cgi?id=172396
+        rdar://problem/30737452
+
+        Reviewed by Jer Noble.
+
+        No new tests because no change to DOM.
+
+        Add support for new HLS UI in AVKit.
+
+        This adds new properties (seekableTimeRangesLastModifiedTime, liveUpdateInterval, minTiming, maxTiming) to WebAVPlayerController.
+        Plumb these properties from AVPlayer up to AVKit.
+
+        Switch WebPlaybackSessionModelMediaElement from updating seekableRangesChanged using timeupdate event to using progress event.
+
+        Enable progress events on iOS.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::HTMLMediaElement):
+        (WebCore::HTMLMediaElement::loadResource):
+        (WebCore::HTMLMediaElement::seekableTimeRangesLastModifiedTime):
+        (WebCore::HTMLMediaElement::liveUpdateInterval):
+        * html/HTMLMediaElement.h:
+        * platform/cf/CoreMediaSoftLink.cpp:
+        * platform/cf/CoreMediaSoftLink.h:
+        * platform/cocoa/WebPlaybackSessionModel.h:
+        (WebCore::WebPlaybackSessionModelClient::seekableRangesChanged):
+        * platform/cocoa/WebPlaybackSessionModelMediaElement.h:
+        * platform/cocoa/WebPlaybackSessionModelMediaElement.mm:
+        (WebCore::WebPlaybackSessionModelMediaElement::updateForEventName):
+        (WebCore::WebPlaybackSessionModelMediaElement::observedEventNames):
+        (WebCore::WebPlaybackSessionModelMediaElement::seekableTimeRangesLastModifiedTime):
+        (WebCore::WebPlaybackSessionModelMediaElement::liveUpdateInterval):
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::seekableTimeRangesLastModifiedTime):
+        (WebCore::MediaPlayer::liveUpdateInterval):
+        * platform/graphics/MediaPlayer.h:
+        * platform/graphics/MediaPlayerPrivate.h:
+        (WebCore::MediaPlayerPrivateInterface::seekableTimeRangesLastModifiedTime):
+        (WebCore::MediaPlayerPrivateInterface::liveUpdateInterval):
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::seekableTimeRangesLastModifiedTime):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::liveUpdateInterval):
+        * platform/ios/WebAVPlayerController.h:
+        * platform/ios/WebAVPlayerController.mm:
+        (-[WebAVPlayerController init]):
+        (-[WebAVPlayerController dealloc]):
+        (-[WebAVPlayerController observeValueForKeyPath:ofObject:change:context:]):
+        (-[WebAVPlayerController updateMinMaxTiming]):
+        (-[WebAVPlayerController hasSeekableLiveStreamingContent]):
+        (+[WebAVPlayerController keyPathsForValuesAffectingHasSeekableLiveStreamingContent]):
+        (-[WebAVPlayerController resetMediaState]):
+        * platform/ios/WebPlaybackSessionInterfaceAVKit.h:
+        * platform/ios/WebPlaybackSessionInterfaceAVKit.mm:
+        (WebCore::WebPlaybackSessionInterfaceAVKit::WebPlaybackSessionInterfaceAVKit):
+        (WebCore::WebPlaybackSessionInterfaceAVKit::resetMediaState):
+        (WebCore::WebPlaybackSessionInterfaceAVKit::seekableRangesChanged):
+        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+        (WebVideoFullscreenControllerContext::seekableRangesChanged):
+        (WebVideoFullscreenControllerContext::seekableTimeRangesLastModifiedTime):
+        (WebVideoFullscreenControllerContext::liveUpdateInterval):
+        * platform/mac/WebPlaybackSessionInterfaceMac.h:
+        * platform/mac/WebPlaybackSessionInterfaceMac.mm:
+        (WebCore::WebPlaybackSessionInterfaceMac::seekableRangesChanged):
+        * platform/spi/cocoa/AVKitSPI.h:
+        * platform/spi/mac/AVFoundationSPI.h:
+
 2017-06-07  Dave Hyatt  <[email protected]>
 
         Laili restaurant menu page does not display full menu

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (217947 => 217948)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2017-06-08 21:47:39 UTC (rev 217948)
@@ -417,7 +417,6 @@
     , m_sentStalledEvent(false)
     , m_sentEndEvent(false)
     , m_pausedInternal(false)
-    , m_sendProgressEvents(true)
     , m_closedCaptionsVisible(false)
     , m_webkitLegacyClosedCaptionOverride(false)
     , m_completelyLoaded(false)
@@ -454,10 +453,6 @@
     m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureToControlControlsManager);
     m_mediaSession->addBehaviorRestriction(MediaElementSession::RequirePlaybackToControlControlsManager);
 
-#if PLATFORM(IOS)
-    m_sendProgressEvents = false;
-#endif
-
     auto* page = document.page();
 
     if (document.settings().invisibleAutoplayNotPermitted())
@@ -1507,8 +1502,7 @@
 
     LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", this, urlForLoggingMedia(m_currentSrc).utf8().data());
 
-    if (m_sendProgressEvents)
-        startProgressEventTimer();
+    startProgressEventTimer();
 
     bool privateMode = document().page() && document().page()->usesEphemeralSession();
     m_player->setPrivateBrowsingMode(privateMode);
@@ -4828,6 +4822,16 @@
     return TimeRanges::create();
 }
 
+double HTMLMediaElement::seekableTimeRangesLastModifiedTime() const
+{
+    return m_player ? m_player->seekableTimeRangesLastModifiedTime() : 0;
+}
+
+double HTMLMediaElement::liveUpdateInterval() const
+{
+    return m_player ? m_player->liveUpdateInterval() : 0;
+}
+
 bool HTMLMediaElement::potentiallyPlaying() const
 {
     if (isBlockedOnMediaController())

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (217947 => 217948)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -232,6 +232,8 @@
     WEBCORE_EXPORT void setWebkitPreservesPitch(bool);
     Ref<TimeRanges> played() override;
     Ref<TimeRanges> seekable() const override;
+    double seekableTimeRangesLastModifiedTime() const;
+    double liveUpdateInterval() const;
     WEBCORE_EXPORT bool ended() const;
     bool autoplay() const;
     bool isAutoplaying() const { return m_autoplaying; }
@@ -1001,10 +1003,6 @@
 
     bool m_pausedInternal : 1;
 
-    // Not all media engines provide enough information about a file to be able to
-    // support progress events so setting m_sendProgressEvents disables them 
-    bool m_sendProgressEvents : 1;
-
     bool m_closedCaptionsVisible : 1;
     bool m_webkitLegacyClosedCaptionOverride : 1;
     bool m_completelyLoaded : 1;

Modified: trunk/Source/WebCore/platform/cf/CoreMediaSoftLink.cpp (217947 => 217948)


--- trunk/Source/WebCore/platform/cf/CoreMediaSoftLink.cpp	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/cf/CoreMediaSoftLink.cpp	2017-06-08 21:47:39 UTC (rev 217948)
@@ -50,6 +50,7 @@
 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeMakeWithSeconds, CMTime, (Float64 seconds, int32_t preferredTimeScale), (seconds, preferredTimeScale))
 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeRangeGetEnd, CMTime, (CMTimeRange range), (range))
 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeRangeMake, CMTimeRange, (CMTime start, CMTime duration), (start, duration))
+SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMTimeRangeEqual, Boolean, (CMTimeRange range1, CMTimeRange range2), (range1, range2))
 
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreMedia, kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms, CFStringRef)
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreMedia, kCMTextMarkupAlignmentType_End, CFStringRef)
@@ -74,6 +75,7 @@
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreMedia, kCMTimeInvalid, CMTime)
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreMedia, kCMTimeZero, CMTime)
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreMedia, kCMTimePositiveInfinity, CMTime)
+SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreMedia, kCMTimeRangeInvalid, CMTimeRange);
 
 #if PLATFORM(COCOA)
 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreMedia, CMFormatDescriptionGetMediaSubType, FourCharCode, (CMFormatDescriptionRef desc), (desc))

Modified: trunk/Source/WebCore/platform/cf/CoreMediaSoftLink.h (217947 => 217948)


--- trunk/Source/WebCore/platform/cf/CoreMediaSoftLink.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/cf/CoreMediaSoftLink.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -63,6 +63,8 @@
 #define CMTimeRangeGetEnd softLink_CoreMedia_CMTimeRangeGetEnd
 SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreMedia, CMTimeRangeMake, CMTimeRange, (CMTime start, CMTime duration), (start, duration))
 #define CMTimeRangeMake softLink_CoreMedia_CMTimeRangeMake
+SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreMedia, CMTimeRangeEqual, Boolean, (CMTimeRange range1, CMTimeRange range2), (range1, range2))
+#define CMTimeRangeEqual softLink_CoreMedia_CMTimeRangeEqual
 
 SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreMedia, kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms, CFStringRef)
 #define kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms get_CoreMedia_kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms()
@@ -110,6 +112,8 @@
 #define kCMTimeZero get_CoreMedia_kCMTimeZero()
 SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreMedia, kCMTimePositiveInfinity, CMTime)
 #define kCMTimePositiveInfinity get_CoreMedia_kCMTimePositiveInfinity()
+SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreMedia, kCMTimeRangeInvalid, CMTimeRange);
+#define kCMTimeRangeInvalid get_CoreMedia_kCMTimeRangeInvalid()
 
 #if PLATFORM(COCOA)
 

Modified: trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModel.h (217947 => 217948)


--- trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModel.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModel.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -68,6 +68,8 @@
     virtual bool isScrubbing() const = 0;
     virtual float playbackRate() const = 0;
     virtual Ref<TimeRanges> seekableRanges() const = 0;
+    virtual double seekableTimeRangesLastModifiedTime() const = 0;
+    virtual double liveUpdateInterval() const = 0;
     virtual bool canPlayFastReverse() const = 0;
     virtual Vector<MediaSelectionOption> audioMediaSelectionOptions() const = 0;
     virtual uint64_t audioMediaSelectedIndex() const = 0;
@@ -88,7 +90,7 @@
     virtual void bufferedTimeChanged(double) { }
     virtual void playbackStartedTimeChanged(double /* playbackStartedTime */) { }
     virtual void rateChanged(bool /* isPlaying */, float /* playbackRate */) { }
-    virtual void seekableRangesChanged(const TimeRanges&) { }
+    virtual void seekableRangesChanged(const TimeRanges&, double /* lastModified */, double /* liveInterval */) { }
     virtual void canPlayFastReverseChanged(bool) { }
     virtual void audioMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& /* options */, uint64_t /* selectedIndex */) { }
     virtual void legibleMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& /* options */, uint64_t /* selectedIndex */) { }

Modified: trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.h (217947 => 217948)


--- trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -79,6 +79,8 @@
     bool isScrubbing() const final { return false; }
     float playbackRate() const final;
     Ref<TimeRanges> seekableRanges() const final;
+    double seekableTimeRangesLastModifiedTime() const final;
+    double liveUpdateInterval() const final;
     bool canPlayFastReverse() const final;
     Vector<MediaSelectionOption> audioMediaSelectionOptions() const final;
     uint64_t audioMediaSelectedIndex() const final;
@@ -94,6 +96,7 @@
     WEBCORE_EXPORT WebPlaybackSessionModelMediaElement();
 
 private:
+    void progressEventTimerFired();
     static const Vector<WTF::AtomicString>& observedEventNames();
     const WTF::AtomicString& eventNameAll();
 
@@ -102,7 +105,7 @@
     HashSet<WebPlaybackSessionModelClient*> m_clients;
     Vector<RefPtr<TextTrack>> m_legibleTracksForMenu;
     Vector<RefPtr<AudioTrack>> m_audioTracksForMenu;
-    
+
     double playbackStartedTime() const;
     void updateMediaSelectionOptions();
     void updateMediaSelectionIndices();

Modified: trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.mm (217947 => 217948)


--- trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.mm	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.mm	2017-06-08 21:47:39 UTC (rev 217948)
@@ -130,14 +130,19 @@
         || eventName == eventNames().timeupdateEvent) {
         auto currentTime = this->currentTime();
         auto anchorTime = [[NSProcessInfo processInfo] systemUptime];
+        for (auto client : m_clients)
+            client->currentTimeChanged(currentTime, anchorTime);
+    }
+
+    if (all
+        || eventName == eventNames().progressEvent) {
         auto bufferedTime = this->bufferedTime();
         auto seekableRanges = this->seekableRanges();
-
+        auto seekableTimeRangesLastModifiedTime = this->seekableTimeRangesLastModifiedTime();
+        auto liveUpdateInterval = this->liveUpdateInterval();
         for (auto client : m_clients) {
-            client->currentTimeChanged(currentTime, anchorTime);
             client->bufferedTimeChanged(bufferedTime);
-            // FIXME: 130788 - find a better event from which to update seekable ranges.
-            client->seekableRangesChanged(seekableRanges);
+            client->seekableRangesChanged(seekableRanges, seekableTimeRangesLastModifiedTime, liveUpdateInterval);
         }
     }
 
@@ -340,6 +345,7 @@
         eventNames().playEvent,
         eventNames().ratechangeEvent,
         eventNames().timeupdateEvent,
+        eventNames().progressEvent,
         eventNames().addtrackEvent,
         eventNames().removetrackEvent,
         eventNames().volumechangeEvent,
@@ -386,6 +392,16 @@
     return m_mediaElement ? m_mediaElement->seekable() : TimeRanges::create();
 }
 
+double WebPlaybackSessionModelMediaElement::seekableTimeRangesLastModifiedTime() const
+{
+    return m_mediaElement ? m_mediaElement->seekableTimeRangesLastModifiedTime() : 0;
+}
+
+double WebPlaybackSessionModelMediaElement::liveUpdateInterval() const
+{
+    return m_mediaElement ? m_mediaElement->liveUpdateInterval() : 0;
+}
+    
 bool WebPlaybackSessionModelMediaElement::canPlayFastReverse() const
 {
     return m_mediaElement ? m_mediaElement->minFastReverseRate() < 0.0 : false;

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp (217947 => 217948)


--- trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp	2017-06-08 21:47:39 UTC (rev 217948)
@@ -148,6 +148,9 @@
     double minTimeSeekable() const override { return 0; }
     std::unique_ptr<PlatformTimeRanges> buffered() const override { return std::make_unique<PlatformTimeRanges>(); }
 
+    double seekableTimeRangesLastModifiedTime() const override { return 0; }
+    double liveUpdateInterval() const override { return 0; }
+
     unsigned long long totalBytes() const override { return 0; }
     bool didLoadingProgress() const override { return false; }
 
@@ -814,6 +817,16 @@
     return m_private->minMediaTimeSeekable();
 }
 
+double MediaPlayer::seekableTimeRangesLastModifiedTime()
+{
+    return m_private->seekableTimeRangesLastModifiedTime();
+}
+
+double MediaPlayer::liveUpdateInterval()
+{
+    return m_private->liveUpdateInterval();
+}
+
 bool MediaPlayer::didLoadingProgress()
 {
     return m_private->didLoadingProgress();

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.h (217947 => 217948)


--- trunk/Source/WebCore/platform/graphics/MediaPlayer.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -389,6 +389,9 @@
     MediaTime minTimeSeekable();
     MediaTime maxTimeSeekable();
 
+    double seekableTimeRangesLastModifiedTime();
+    double liveUpdateInterval();
+
     bool didLoadingProgress();
 
     double volume() const;

Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h (217947 => 217948)


--- trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -142,6 +142,8 @@
     virtual double minTimeSeekable() const { return 0; }
     virtual MediaTime minMediaTimeSeekable() const { return MediaTime::createWithDouble(minTimeSeekable()); }
     virtual std::unique_ptr<PlatformTimeRanges> buffered() const = 0;
+    virtual double seekableTimeRangesLastModifiedTime() const { return 0; }
+    virtual double liveUpdateInterval() const { return 0; }
 
     virtual unsigned long long totalBytes() const { return 0; }
     virtual bool didLoadingProgress() const = 0;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h (217947 => 217948)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -209,6 +209,9 @@
     MediaPlayerPrivateAVFoundation::AssetStatus assetStatus() const override;
     long assetErrorCode() const override;
 
+    double seekableTimeRangesLastModifiedTime() const override;
+    double liveUpdateInterval() const override;
+
     void checkPlayability() override;
     void setRateDouble(double) override;
     double rate() const override;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (217947 => 217948)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2017-06-08 21:47:39 UTC (rev 217948)
@@ -1470,6 +1470,24 @@
     return m_cachedRate;
 }
 
+double MediaPlayerPrivateAVFoundationObjC::seekableTimeRangesLastModifiedTime() const
+{
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000)
+    return [m_avPlayerItem seekableTimeRangesLastModifiedTime];
+#else
+    return 0;
+#endif
+}
+
+double MediaPlayerPrivateAVFoundationObjC::liveUpdateInterval() const
+{
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000)
+    return [m_avPlayerItem liveUpdateInterval];
+#else
+    return 0;
+#endif
+}
+
 void MediaPlayerPrivateAVFoundationObjC::setPreservesPitch(bool preservesPitch)
 {
     if (m_avPlayerItem)

Modified: trunk/Source/WebCore/platform/ios/WebAVPlayerController.h (217947 => 217948)


--- trunk/Source/WebCore/platform/ios/WebAVPlayerController.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/ios/WebAVPlayerController.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -87,6 +87,15 @@
 @property BOOL allowsExternalPlayback;
 @property (getter=isPictureInPicturePossible) BOOL pictureInPicturePossible;
 @property (getter=isPictureInPictureInterrupted) BOOL pictureInPictureInterrupted;
+
+@property NSTimeInterval seekableTimeRangesLastModifiedTime;
+@property NSTimeInterval liveUpdateInterval;
+
+@property (NS_NONATOMIC_IOSONLY, retain, readwrite) AVValueTiming *minTiming;
+@property (NS_NONATOMIC_IOSONLY, retain, readwrite) AVValueTiming *maxTiming;
+
+- (void)resetMediaState;
+
 @end
 
 #endif

Modified: trunk/Source/WebCore/platform/ios/WebAVPlayerController.mm (217947 => 217948)


--- trunk/Source/WebCore/platform/ios/WebAVPlayerController.mm	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/ios/WebAVPlayerController.mm	2017-06-08 21:47:39 UTC (rev 217948)
@@ -42,11 +42,21 @@
 
 SOFT_LINK_FRAMEWORK_OPTIONAL(AVKit)
 SOFT_LINK_CLASS_OPTIONAL(AVKit, AVPlayerController)
+SOFT_LINK_CLASS_OPTIONAL(AVKit, AVValueTiming)
 
 using namespace WebCore;
 
-@implementation WebAVPlayerController
+static void * WebAVPlayerControllerSeekableTimeRangesObserverContext = &WebAVPlayerControllerSeekableTimeRangesObserverContext;
+static void * WebAVPlayerControllerHasLiveStreamingContentObserverContext = &WebAVPlayerControllerHasLiveStreamingContentObserverContext;
 
+static double WebAVPlayerControllerLiveStreamSeekableTimeRangeDurationHysteresisDelta = 3.0; // Minimum delta of time required to change the duration of the seekable time range.
+static double WebAVPlayerControllerLiveStreamMinimumTargetDuration = 1.0; // Minimum segment duration to be considered valid.
+static double WebAVPlayerControllerLiveStreamSeekableTimeRangeMinimumDuration = 30.0;
+
+@implementation WebAVPlayerController {
+    BOOL _liveStreamEventModePossible;
+}
+
 - (instancetype)init
 {
     if (!getAVPlayerControllerClass())
@@ -57,11 +67,20 @@
 
     initAVPlayerController();
     self.playerControllerProxy = [[allocAVPlayerControllerInstance() init] autorelease];
+    _liveStreamEventModePossible = YES;
+
+    [self addObserver:self forKeyPath:@"seekableTimeRanges" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:WebAVPlayerControllerSeekableTimeRangesObserverContext];
+    [self addObserver:self forKeyPath:@"hasLiveStreamingContent" options:NSKeyValueObservingOptionInitial context:WebAVPlayerControllerHasLiveStreamingContentObserverContext];
+
+
     return self;
 }
 
 - (void)dealloc
 {
+    [self removeObserver:self forKeyPath:@"seekableTimeRanges" context:WebAVPlayerControllerSeekableTimeRangesObserverContext];
+    [self removeObserver:self forKeyPath:@"hasLiveStreamingContent" context:WebAVPlayerControllerHasLiveStreamingContentObserverContext];
+
     [_playerControllerProxy release];
     [_loadedTimeRanges release];
     [_seekableTimeRanges release];
@@ -420,6 +439,121 @@
         self.delegate->toggleMuted();
 }
 
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+    UNUSED_PARAM(object);
+    UNUSED_PARAM(keyPath);
+
+    if (WebAVPlayerControllerSeekableTimeRangesObserverContext == context) {
+        NSArray *oldArray = change[NSKeyValueChangeOldKey];
+        NSArray *newArray = change[NSKeyValueChangeNewKey];
+        if ([oldArray isKindOfClass:[NSArray class]] && [newArray isKindOfClass:[NSArray class]]) {
+            CMTimeRange oldSeekableTimeRange = [oldArray count] > 0 ? [[oldArray firstObject] CMTimeRangeValue] : kCMTimeRangeInvalid;
+            CMTimeRange newSeekableTimeRange = [newArray count] > 0 ? [[newArray firstObject] CMTimeRangeValue] : kCMTimeRangeInvalid;
+            if (!CMTimeRangeEqual(oldSeekableTimeRange, newSeekableTimeRange)) {
+                if (CMTIMERANGE_IS_VALID(newSeekableTimeRange) && CMTIMERANGE_IS_VALID(oldSeekableTimeRange) && _liveStreamEventModePossible && !CMTimeRangeContainsTime(newSeekableTimeRange, oldSeekableTimeRange.start))
+                    _liveStreamEventModePossible = NO;
+
+                [self updateMinMaxTiming];
+            }
+        }
+    } else if (WebAVPlayerControllerHasLiveStreamingContentObserverContext == context)
+        [self updateMinMaxTiming];
+}
+
+- (void)updateMinMaxTiming
+{
+    AVValueTiming *newMinTiming = nil;
+    AVValueTiming *newMaxTiming = nil;
+
+    // For live streams value timings for the min and max times are needed.
+    if ([self hasLiveStreamingContent] && ([[self seekableTimeRanges] count] > 0)) {
+        CMTimeRange seekableTimeRange = [[[self seekableTimeRanges] firstObject] CMTimeRangeValue];
+        if (CMTIMERANGE_IS_VALID(seekableTimeRange)) {
+            NSTimeInterval oldMinTime = [[self minTiming] currentValue];
+            NSTimeInterval oldMaxTime = [[self maxTiming] currentValue];
+            NSTimeInterval newMinTime = CMTimeGetSeconds(seekableTimeRange.start);
+            NSTimeInterval newMaxTime = CMTimeGetSeconds(seekableTimeRange.start) + CMTimeGetSeconds(seekableTimeRange.duration) + (CACurrentMediaTime() - [self seekableTimeRangesLastModifiedTime]);
+            double newMinTimingRate = _liveStreamEventModePossible ? 0.0 : 1.0;
+            BOOL minTimingNeedsUpdate = YES;
+            BOOL maxTimingNeedsUpdate = YES;
+
+            if (isfinite([self liveUpdateInterval]) && [self liveUpdateInterval] > WebAVPlayerControllerLiveStreamMinimumTargetDuration) {
+                // Only update the timing if the new time differs by one segment duration plus the hysteresis delta.
+                minTimingNeedsUpdate = isnan(oldMinTime) || (fabs(oldMinTime - newMinTime) > [self liveUpdateInterval] + WebAVPlayerControllerLiveStreamSeekableTimeRangeDurationHysteresisDelta) || ([[self minTiming] rate] != newMinTimingRate);
+                maxTimingNeedsUpdate = isnan(oldMaxTime) || (fabs(oldMaxTime - newMaxTime) > [self liveUpdateInterval] + WebAVPlayerControllerLiveStreamSeekableTimeRangeDurationHysteresisDelta);
+            }
+
+            if (minTimingNeedsUpdate || maxTimingNeedsUpdate) {
+                newMinTiming = [getAVValueTimingClass() valueTimingWithAnchorValue:newMinTime anchorTimeStamp:[getAVValueTimingClass() currentTimeStamp] rate:newMinTimingRate];
+                newMaxTiming = [getAVValueTimingClass() valueTimingWithAnchorValue:newMaxTime anchorTimeStamp:[getAVValueTimingClass() currentTimeStamp] rate:1.0];
+            } else {
+                newMinTiming = [self minTiming];
+                newMaxTiming = [self maxTiming];
+            }
+        }
+    }
+
+    if (!newMinTiming)
+        newMinTiming = [getAVValueTimingClass() valueTimingWithAnchorValue:[self minTime] anchorTimeStamp:NAN rate:0.0];
+
+    if (!newMaxTiming)
+        newMaxTiming = [getAVValueTimingClass() valueTimingWithAnchorValue:[self maxTime] anchorTimeStamp:NAN rate:0.0];
+
+    [self setMinTiming:newMinTiming];
+    [self setMaxTiming:newMaxTiming];
+}
+
+
+- (BOOL)hasSeekableLiveStreamingContent
+{
+    BOOL hasSeekableLiveStreamingContent = NO;
+
+    if ([self hasLiveStreamingContent] && [self minTiming] && [self maxTiming] && isfinite([self liveUpdateInterval]) && [self liveUpdateInterval] > WebAVPlayerControllerLiveStreamMinimumTargetDuration && ([self seekableTimeRangesLastModifiedTime] != 0.0)) {
+        NSTimeInterval timeStamp = [getAVValueTimingClass() currentTimeStamp];
+        NSTimeInterval minTime = [[self minTiming] valueForTimeStamp:timeStamp];
+        NSTimeInterval maxTime = [[self maxTiming] valueForTimeStamp:timeStamp];
+        hasSeekableLiveStreamingContent = ((maxTime - minTime) > WebAVPlayerControllerLiveStreamSeekableTimeRangeMinimumDuration);
+    }
+
+    return hasSeekableLiveStreamingContent;
+}
+
++ (NSSet *)keyPathsForValuesAffectingHasSeekableLiveStreamingContent
+{
+    return [NSSet setWithObjects:@"hasLiveStreamingContent", @"minTiming", @"maxTiming", @"seekableTimeRangesLastModifiedTime", nil];
+}
+
+- (void)resetMediaState
+{
+    self.contentDuration = 0;
+    self.maxTime = 0;
+    self.contentDurationWithinEndTimes = 0;
+    self.loadedTimeRanges = @[];
+
+    self.canPlay = NO;
+    self.canPause = NO;
+    self.canTogglePlayback = NO;
+    self.hasEnabledAudio = NO;
+    self.canSeek = NO;
+    self.minTime = 0;
+    self.status = AVPlayerControllerStatusUnknown;
+
+    self.timing = nil;
+    self.rate = 0;
+
+    self.seekableTimeRanges = [NSMutableArray array];
+
+    self.canScanBackward = NO;
+
+    self.audioMediaSelectionOptions = nil;
+    self.currentAudioMediaSelectionOption = nil;
+
+    self.legibleMediaSelectionOptions = nil;
+    self.currentLegibleMediaSelectionOption = nil;
+    _liveStreamEventModePossible = YES;
+}
+
 @end
 
 @implementation WebAVMediaSelectionOption

Modified: trunk/Source/WebCore/platform/ios/WebPlaybackSessionInterfaceAVKit.h (217947 => 217948)


--- trunk/Source/WebCore/platform/ios/WebPlaybackSessionInterfaceAVKit.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/ios/WebPlaybackSessionInterfaceAVKit.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -76,7 +76,7 @@
     WEBCORE_EXPORT void currentTimeChanged(double currentTime, double anchorTime) override;
     WEBCORE_EXPORT void bufferedTimeChanged(double) override;
     WEBCORE_EXPORT void rateChanged(bool isPlaying, float playbackRate) override;
-    WEBCORE_EXPORT void seekableRangesChanged(const TimeRanges&) override;
+    WEBCORE_EXPORT void seekableRangesChanged(const TimeRanges&, double lastModifiedTime, double liveUpdateInterval) override;
     WEBCORE_EXPORT void canPlayFastReverseChanged(bool) override;
     WEBCORE_EXPORT void audioMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex) override;
     WEBCORE_EXPORT void legibleMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex) override;

Modified: trunk/Source/WebCore/platform/ios/WebPlaybackSessionInterfaceAVKit.mm (217947 => 217948)


--- trunk/Source/WebCore/platform/ios/WebPlaybackSessionInterfaceAVKit.mm	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/ios/WebPlaybackSessionInterfaceAVKit.mm	2017-06-08 21:47:39 UTC (rev 217948)
@@ -60,7 +60,7 @@
     currentTimeChanged(model.currentTime(), [[NSProcessInfo processInfo] systemUptime]);
     bufferedTimeChanged(model.bufferedTime());
     rateChanged(model.isPlaying(), model.playbackRate());
-    seekableRangesChanged(model.seekableRanges());
+    seekableRangesChanged(model.seekableRanges(), model.seekableTimeRangesLastModifiedTime(), model.liveUpdateInterval());
     canPlayFastReverseChanged(model.canPlayFastReverse());
     audioMediaSelectionOptionsChanged(model.audioMediaSelectionOptions(), model.audioMediaSelectedIndex());
     legibleMediaSelectionOptionsChanged(model.legibleMediaSelectionOptions(), model.legibleMediaSelectedIndex());
@@ -78,33 +78,7 @@
 
 void WebPlaybackSessionInterfaceAVKit::resetMediaState()
 {
-    WebAVPlayerController* playerController = m_playerController.get();
-
-    playerController.contentDuration = 0;
-    playerController.maxTime = 0;
-    playerController.contentDurationWithinEndTimes = 0;
-    playerController.loadedTimeRanges = @[];
-
-    playerController.canPlay = NO;
-    playerController.canPause = NO;
-    playerController.canTogglePlayback = NO;
-    playerController.hasEnabledAudio = NO;
-    playerController.canSeek = NO;
-    playerController.minTime = 0;
-    playerController.status = AVPlayerControllerStatusUnknown;
-
-    playerController.timing = nil;
-    playerController.rate = 0;
-
-    playerController.seekableTimeRanges = [NSMutableArray array];
-
-    playerController.canScanBackward = NO;
-
-    playerController.audioMediaSelectionOptions = nil;
-    playerController.currentAudioMediaSelectionOption = nil;
-
-    playerController.legibleMediaSelectionOptions = nil;
-    playerController.currentLegibleMediaSelectionOption = nil;
+    [m_playerController resetMediaState];
 }
 
 void WebPlaybackSessionInterfaceAVKit::durationChanged(double duration)
@@ -152,7 +126,7 @@
     [m_playerController setRate:isPlaying ? playbackRate : 0.];
 }
 
-void WebPlaybackSessionInterfaceAVKit::seekableRangesChanged(const TimeRanges& timeRanges)
+void WebPlaybackSessionInterfaceAVKit::seekableRangesChanged(const TimeRanges& timeRanges, double lastModifiedTime, double liveUpdateInterval)
 {
     RetainPtr<NSMutableArray> seekableRanges = adoptNS([[NSMutableArray alloc] init]);
 
@@ -165,6 +139,8 @@
     }
 
     [m_playerController setSeekableTimeRanges:seekableRanges.get()];
+    [m_playerController setSeekableTimeRangesLastModifiedTime: lastModifiedTime];
+    [m_playerController setLiveUpdateInterval:liveUpdateInterval];
 }
 
 void WebPlaybackSessionInterfaceAVKit::canPlayFastReverseChanged(bool canPlayFastReverse)

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm (217947 => 217948)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2017-06-08 21:47:39 UTC (rev 217948)
@@ -155,6 +155,8 @@
     bool isScrubbing() const override { return false; }
     float playbackRate() const override;
     Ref<TimeRanges> seekableRanges() const override;
+    double seekableTimeRangesLastModifiedTime() const override;
+    double liveUpdateInterval() const override;
     bool canPlayFastReverse() const override;
     Vector<MediaSelectionOption> audioMediaSelectionOptions() const override;
     uint64_t audioMediaSelectedIndex() const override;
@@ -172,7 +174,7 @@
     void currentTimeChanged(double currentTime, double anchorTime) override;
     void bufferedTimeChanged(double) override;
     void rateChanged(bool isPlaying, float playbackRate) override;
-    void seekableRangesChanged(const TimeRanges&) override;
+    void seekableRangesChanged(const TimeRanges&, double lastModifiedTime, double liveUpdateInterval) override;
     void canPlayFastReverseChanged(bool) override;
     void audioMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex) override;
     void legibleMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& options, uint64_t selectedIndex) override;
@@ -351,18 +353,18 @@
         client->videoDimensionsChanged(videoDimensions);
 }
 
-void WebVideoFullscreenControllerContext::seekableRangesChanged(const TimeRanges& timeRanges)
+void WebVideoFullscreenControllerContext::seekableRangesChanged(const TimeRanges& timeRanges, double lastModifiedTime, double liveUpdateInterval)
 {
     if (WebThreadIsCurrent()) {
         RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
-        dispatch_async(dispatch_get_main_queue(), [protectedThis, platformTimeRanges = timeRanges.ranges()] {
-            protectedThis->seekableRangesChanged(TimeRanges::create(platformTimeRanges));
+        dispatch_async(dispatch_get_main_queue(), [protectedThis, platformTimeRanges = timeRanges.ranges(), lastModifiedTime, liveUpdateInterval] {
+            protectedThis->seekableRangesChanged(TimeRanges::create(platformTimeRanges), lastModifiedTime, liveUpdateInterval);
         });
         return;
     }
 
     for (auto &client : m_playbackClients)
-        client->seekableRangesChanged(timeRanges);
+        client->seekableRangesChanged(timeRanges, lastModifiedTime, liveUpdateInterval);
 }
 
 void WebVideoFullscreenControllerContext::canPlayFastReverseChanged(bool canPlayFastReverse)
@@ -729,6 +731,18 @@
     return m_playbackModel ? m_playbackModel->seekableRanges() : TimeRanges::create();
 }
 
+double WebVideoFullscreenControllerContext::seekableTimeRangesLastModifiedTime() const
+{
+    ASSERT(isUIThread());
+    return m_playbackModel ? m_playbackModel->seekableTimeRangesLastModifiedTime() : 0;
+}
+
+double WebVideoFullscreenControllerContext::liveUpdateInterval() const
+{
+    ASSERT(isUIThread());
+    return m_playbackModel ? m_playbackModel->liveUpdateInterval() : 0;
+}
+
 bool WebVideoFullscreenControllerContext::canPlayFastReverse() const
 {
     ASSERT(isUIThread());

Modified: trunk/Source/WebCore/platform/mac/WebPlaybackSessionInterfaceMac.h (217947 => 217948)


--- trunk/Source/WebCore/platform/mac/WebPlaybackSessionInterfaceMac.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/mac/WebPlaybackSessionInterfaceMac.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -56,7 +56,7 @@
     WEBCORE_EXPORT void durationChanged(double) final;
     WEBCORE_EXPORT void currentTimeChanged(double /*currentTime*/, double /*anchorTime*/) final;
     WEBCORE_EXPORT void rateChanged(bool /*isPlaying*/, float /*playbackRate*/) final;
-    WEBCORE_EXPORT void seekableRangesChanged(const TimeRanges&) final;
+    WEBCORE_EXPORT void seekableRangesChanged(const TimeRanges&, double /*lastModifiedTime*/, double /*liveUpdateInterval*/) final;
     WEBCORE_EXPORT void audioMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& /*options*/, uint64_t /*selectedIndex*/) final;
     WEBCORE_EXPORT void legibleMediaSelectionOptionsChanged(const Vector<MediaSelectionOption>& /*options*/, uint64_t /*selectedIndex*/) final;
     WEBCORE_EXPORT void audioMediaSelectionIndexChanged(uint64_t) final;

Modified: trunk/Source/WebCore/platform/mac/WebPlaybackSessionInterfaceMac.mm (217947 => 217948)


--- trunk/Source/WebCore/platform/mac/WebPlaybackSessionInterfaceMac.mm	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/mac/WebPlaybackSessionInterfaceMac.mm	2017-06-08 21:47:39 UTC (rev 217948)
@@ -130,7 +130,7 @@
 }
 #endif
 
-void WebPlaybackSessionInterfaceMac::seekableRangesChanged(const TimeRanges& timeRanges)
+void WebPlaybackSessionInterfaceMac::seekableRangesChanged(const TimeRanges& timeRanges, double, double)
 {
 #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER)
     [playBackControlsManager() setSeekableTimeRanges:timeRangesToArray(timeRanges).get()];

Modified: trunk/Source/WebCore/platform/spi/cocoa/AVKitSPI.h (217947 => 217948)


--- trunk/Source/WebCore/platform/spi/cocoa/AVKitSPI.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/spi/cocoa/AVKitSPI.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -147,6 +147,12 @@
 @interface AVValueTiming ()
 + (AVValueTiming *)valueTimingWithAnchorValue:(double)anchorValue anchorTimeStamp:(NSTimeInterval)timeStamp rate:(double)rate;
 @property (NS_NONATOMIC_IOSONLY, readonly) double currentValue;
+@property (NS_NONATOMIC_IOSONLY, readonly) double rate;
+@property (NS_NONATOMIC_IOSONLY, readonly) NSTimeInterval anchorTimeStamp;
+@property (NS_NONATOMIC_IOSONLY, readonly) double anchorValue;
+
++ (NSTimeInterval)currentTimeStamp;
+- (double)valueForTimeStamp:(NSTimeInterval)timeStamp;
 @end
 
 NS_ASSUME_NONNULL_END

Modified: trunk/Source/WebCore/platform/spi/mac/AVFoundationSPI.h (217947 => 217948)


--- trunk/Source/WebCore/platform/spi/mac/AVFoundationSPI.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebCore/platform/spi/mac/AVFoundationSPI.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -32,6 +32,7 @@
 
 #import <AVFoundation/AVAssetCache_Private.h>
 #import <AVFoundation/AVOutputContext.h>
+#import <AVFoundation/AVPlayerItem_Private.h>
 #import <AVFoundation/AVPlayerLayer_Private.h>
 #import <AVFoundation/AVPlayer_Private.h>
 
@@ -47,6 +48,16 @@
 
 #import <AVFoundation/AVPlayer.h>
 
+
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000)
+NS_ASSUME_NONNULL_BEGIN
+@interface AVPlayerItem ()
+@property (nonatomic, readonly) NSTimeInterval seekableTimeRangesLastModifiedTime NS_AVAILABLE(10_13, 11_0);
+@property (nonatomic, readonly) NSTimeInterval liveUpdateInterval;
+@end
+NS_ASSUME_NONNULL_END
+#endif // (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000)
+
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
 
 NS_ASSUME_NONNULL_BEGIN

Modified: trunk/Source/WebKit2/ChangeLog (217947 => 217948)


--- trunk/Source/WebKit2/ChangeLog	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebKit2/ChangeLog	2017-06-08 21:47:39 UTC (rev 217948)
@@ -1,3 +1,25 @@
+2017-06-08  Jeremy Jones  <[email protected]>
+
+        Implement additional AVPlayerController interfaces for minTime and maxTime.
+        https://bugs.webkit.org/show_bug.cgi?id=172396
+        rdar://problem/30737452
+
+        Reviewed by Jer Noble.
+
+        Add support for new HLS UI in AVKit.
+
+        Plumb seekableTimeRangesLastModifiedTime and liveUpdateInterval across process boundaries.
+
+        * UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h:
+        * UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in:
+        * UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm:
+        (WebKit::WebPlaybackSessionModelContext::setSeekableRanges):
+        (WebKit::WebPlaybackSessionManagerProxy::setSeekableRangesVector):
+        * WebProcess/cocoa/WebPlaybackSessionManager.h:
+        * WebProcess/cocoa/WebPlaybackSessionManager.mm:
+        (WebKit::WebPlaybackSessionInterfaceContext::seekableRangesChanged):
+        (WebKit::WebPlaybackSessionManager::seekableRangesChanged):
+
 2017-06-08  Chris Dumez  <[email protected]>
 
         Use WTF::Function more in SpeculativeLoadManager

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h (217947 => 217948)


--- trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -75,7 +75,7 @@
     void setBufferedTime(double);
     void setPlaybackStartedTime(double);
     void setRate(bool isPlaying, float playbackRate);
-    void setSeekableRanges(WebCore::TimeRanges&);
+    void setSeekableRanges(WebCore::TimeRanges&, double lastModifiedTime, double liveUpdateInterval);
     void setCanPlayFastReverse(bool);
     void setAudioMediaSelectionOptions(const Vector<WebCore::MediaSelectionOption>& options, uint64_t index);
     void setLegibleMediaSelectionOptions(const Vector<WebCore::MediaSelectionOption>& options, uint64_t index);
@@ -118,6 +118,8 @@
     bool isScrubbing() const final { return m_isScrubbing; }
     float playbackRate() const final { return m_playbackRate; }
     Ref<WebCore::TimeRanges> seekableRanges() const final { return m_seekableRanges.copyRef(); }
+    double seekableTimeRangesLastModifiedTime() const final { return m_seekableTimeRangesLastModifiedTime; }
+    double liveUpdateInterval() const { return m_liveUpdateInterval; }
     bool canPlayFastReverse() const final { return m_canPlayFastReverse; }
     Vector<WebCore::MediaSelectionOption> audioMediaSelectionOptions() const final { return m_audioMediaSelectionOptions; }
     uint64_t audioMediaSelectedIndex() const final { return m_audioMediaSelectedIndex; }
@@ -141,6 +143,8 @@
     bool m_isScrubbing { false };
     float m_playbackRate { 0 };
     Ref<WebCore::TimeRanges> m_seekableRanges { WebCore::TimeRanges::create() };
+    double m_seekableTimeRangesLastModifiedTime { 0 };
+    double m_liveUpdateInterval { 0 };
     bool m_canPlayFastReverse { false };
     Vector<WebCore::MediaSelectionOption> m_audioMediaSelectionOptions;
     uint64_t m_audioMediaSelectedIndex { 0 };
@@ -184,7 +188,7 @@
     void resetMediaState(uint64_t contextId);
     void setCurrentTime(uint64_t contextId, double currentTime, double hostTime);
     void setBufferedTime(uint64_t contextId, double bufferedTime);
-    void setSeekableRangesVector(uint64_t contextId, Vector<std::pair<double, double>> ranges);
+    void setSeekableRangesVector(uint64_t contextId, Vector<std::pair<double, double>> ranges, double lastModifiedTime, double liveUpdateInterval);
     void setCanPlayFastReverse(uint64_t contextId, bool value);
     void setAudioMediaSelectionOptions(uint64_t contextId, Vector<WebCore::MediaSelectionOption> options, uint64_t selectedIndex);
     void setLegibleMediaSelectionOptions(uint64_t contextId, Vector<WebCore::MediaSelectionOption> options, uint64_t selectedIndex);

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in (217947 => 217948)


--- trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.messages.in	2017-06-08 21:47:39 UTC (rev 217948)
@@ -25,7 +25,7 @@
     ResetMediaState(uint64_t contextId)
     SetCurrentTime(uint64_t contextId, double currentTime, double hostTime)
     SetBufferedTime(uint64_t contextId, double bufferedTime)
-    SetSeekableRangesVector(uint64_t contextId, Vector<std::pair<double, double>> ranges)
+    SetSeekableRangesVector(uint64_t contextId, Vector<std::pair<double, double>> ranges, double lastModifiedTime, double liveUpdateInterval)
     SetCanPlayFastReverse(uint64_t contextId, bool value)
     SetAudioMediaSelectionOptions(uint64_t contextId, Vector<WebCore::MediaSelectionOption> options, uint64_t selectedIndex)
     SetLegibleMediaSelectionOptions(uint64_t contextId, Vector<WebCore::MediaSelectionOption> options, uint64_t selectedIndex)

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm (217947 => 217948)


--- trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebPlaybackSessionManagerProxy.mm	2017-06-08 21:47:39 UTC (rev 217948)
@@ -180,11 +180,13 @@
         client->rateChanged(isPlaying, playbackRate);
 }
 
-void WebPlaybackSessionModelContext::setSeekableRanges(WebCore::TimeRanges& seekableRanges)
+void WebPlaybackSessionModelContext::setSeekableRanges(WebCore::TimeRanges& seekableRanges, double lastModifiedTime, double liveUpdateInterval)
 {
     m_seekableRanges = seekableRanges;
+    m_seekableTimeRangesLastModifiedTime = lastModifiedTime;
+    m_liveUpdateInterval = liveUpdateInterval;
     for (auto* client : m_clients)
-        client->seekableRangesChanged(seekableRanges);
+        client->seekableRangesChanged(seekableRanges, lastModifiedTime, liveUpdateInterval);
 }
 
 void WebPlaybackSessionModelContext::setCanPlayFastReverse(bool canPlayFastReverse)
@@ -376,7 +378,7 @@
     ensureModel(contextId).setBufferedTime(bufferedTime);
 }
 
-void WebPlaybackSessionManagerProxy::setSeekableRangesVector(uint64_t contextId, Vector<std::pair<double, double>> ranges)
+void WebPlaybackSessionManagerProxy::setSeekableRangesVector(uint64_t contextId, Vector<std::pair<double, double>> ranges, double lastModifiedTime, double liveUpdateInterval)
 {
     Ref<TimeRanges> timeRanges = TimeRanges::create();
     for (const auto& range : ranges) {
@@ -386,7 +388,7 @@
         timeRanges->add(range.first, range.second);
     }
 
-    ensureModel(contextId).setSeekableRanges(timeRanges);
+    ensureModel(contextId).setSeekableRanges(timeRanges, lastModifiedTime, liveUpdateInterval);
 }
 
 void WebPlaybackSessionManagerProxy::setCanPlayFastReverse(uint64_t contextId, bool value)

Modified: trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.h (217947 => 217948)


--- trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.h	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.h	2017-06-08 21:47:39 UTC (rev 217948)
@@ -79,7 +79,7 @@
     void bufferedTimeChanged(double) final;
     void playbackStartedTimeChanged(double playbackStartedTime) final;
     void rateChanged(bool isPlaying, float playbackRate) final;
-    void seekableRangesChanged(const WebCore::TimeRanges&) final;
+    void seekableRangesChanged(const WebCore::TimeRanges&, double lastModifiedTime, double liveUpdateInterval) final;
     void canPlayFastReverseChanged(bool value) final;
     void audioMediaSelectionOptionsChanged(const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex) final;
     void legibleMediaSelectionOptionsChanged(const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex) final;
@@ -128,7 +128,7 @@
     void bufferedTimeChanged(uint64_t contextId, double bufferedTime);
     void playbackStartedTimeChanged(uint64_t contextId, double playbackStartedTime);
     void rateChanged(uint64_t contextId, bool isPlaying, float playbackRate);
-    void seekableRangesChanged(uint64_t contextId, const WebCore::TimeRanges&);
+    void seekableRangesChanged(uint64_t contextId, const WebCore::TimeRanges&, double lastModifiedTime, double liveUpdateInterval);
     void canPlayFastReverseChanged(uint64_t contextId, bool value);
     void audioMediaSelectionOptionsChanged(uint64_t contextId, const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex);
     void legibleMediaSelectionOptionsChanged(uint64_t contextId, const Vector<WebCore::MediaSelectionOption>& options, uint64_t selectedIndex);

Modified: trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.mm (217947 => 217948)


--- trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.mm	2017-06-08 21:37:50 UTC (rev 217947)
+++ trunk/Source/WebKit2/WebProcess/cocoa/WebPlaybackSessionManager.mm	2017-06-08 21:47:39 UTC (rev 217948)
@@ -101,10 +101,10 @@
         m_manager->playbackStartedTimeChanged(m_contextId, playbackStartedTime);
 }
 
-void WebPlaybackSessionInterfaceContext::seekableRangesChanged(const WebCore::TimeRanges& ranges)
+void WebPlaybackSessionInterfaceContext::seekableRangesChanged(const WebCore::TimeRanges& ranges, double lastModifiedTime, double liveUpdateInterval)
 {
     if (m_manager)
-        m_manager->seekableRangesChanged(m_contextId, ranges);
+        m_manager->seekableRangesChanged(m_contextId, ranges, lastModifiedTime, liveUpdateInterval);
 }
 
 void WebPlaybackSessionInterfaceContext::canPlayFastReverseChanged(bool value)
@@ -318,7 +318,7 @@
     m_page->send(Messages::WebPlaybackSessionManagerProxy::SetRate(contextId, isPlaying, playbackRate), m_page->pageID());
 }
 
-void WebPlaybackSessionManager::seekableRangesChanged(uint64_t contextId, const WebCore::TimeRanges& timeRanges)
+void WebPlaybackSessionManager::seekableRangesChanged(uint64_t contextId, const WebCore::TimeRanges& timeRanges, double lastModifiedTime, double liveUpdateInterval)
 {
     Vector<std::pair<double, double>> rangesVector;
     for (unsigned i = 0; i < timeRanges.length(); i++) {
@@ -326,7 +326,7 @@
         double end = timeRanges.ranges().end(i).toDouble();
         rangesVector.append({ start, end });
     }
-    m_page->send(Messages::WebPlaybackSessionManagerProxy::SetSeekableRangesVector(contextId, WTFMove(rangesVector)), m_page->pageID());
+    m_page->send(Messages::WebPlaybackSessionManagerProxy::SetSeekableRangesVector(contextId, WTFMove(rangesVector), lastModifiedTime, liveUpdateInterval), m_page->pageID());
 }
 
 void WebPlaybackSessionManager::canPlayFastReverseChanged(uint64_t contextId, bool value)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to