Changeset 293488 in webkit
- Timestamp:
- Apr 26, 2022 5:29:15 PM (3 months ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 14 edited
-
ChangeLog (modified) (1 diff)
-
Modules/mediasession/MediaSession.cpp (modified) (2 diffs)
-
Modules/mediasession/MediaSession.h (modified) (2 diffs)
-
html/HTMLMediaElement.cpp (modified) (6 diffs)
-
html/MediaElementSession.cpp (modified) (7 diffs)
-
html/MediaElementSession.h (modified) (1 diff)
-
platform/audio/NowPlayingInfo.h (modified) (5 diffs)
-
platform/audio/PlatformMediaSession.cpp (modified) (1 diff)
-
platform/audio/PlatformMediaSession.h (modified) (1 diff)
-
platform/audio/PlatformMediaSessionManager.h (modified) (1 diff)
-
platform/audio/cocoa/MediaSessionManagerCocoa.h (modified) (1 diff)
-
platform/audio/cocoa/MediaSessionManagerCocoa.mm (modified) (2 diffs)
-
platform/audio/glib/MediaSessionManagerGLib.cpp (modified) (1 diff)
-
platform/audio/glib/MediaSessionManagerGLib.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r293486 r293488 1 2022-04-26 Jean-Yves Avenard <jya@apple.com> 2 3 MediaSession.setPositionState() does not work. 4 https://bugs.webkit.org/show_bug.cgi?id=237196 5 6 Reviewed by Eric Carlson. 7 8 Use MediaSession's positionState if present when constructing NowPlaying 9 MediaRemote data. 10 We emulate what the media-session position would have been had the 11 time progressed according to the playback rate. 12 As such, we need to tell the media-session when no action handlers are 13 set that the media was paused or played again. 14 When seeking, we update the new time position and continue according to 15 the set playback rate. 16 17 Tested manually with the following scenarios: 18 - Set a page only defining the media-session's position state once 19 - Let the media element play by default, check the Now Playing position 20 - Pause/Play using Now Playing control and checks that the time doesn't 21 jump around. 22 - Seek using Now Playing and check that the media seeks properly and that 23 the Now Playing positon progress from the seek point according to the 24 media-session's playback rate. 25 - Seek using default media control and check the same as above. 26 - Seek using default media control, then pause in Now Playing: check that 27 the playback position doesn't jump around. 28 29 We don't have a way to properly test the MediaRemote 30 external framework and with existing MediaSession API tests currently 31 disabled following bug 221514. 32 33 * Modules/mediasession/MediaSession.cpp: 34 (WebCore::MediaSession::setPlaybackState): 35 (WebCore::MediaSession::updateReportedPosition): 36 (WebCore::MediaSession::willBeginPlayback): 37 (WebCore::MediaSession::willPausePlayback): 38 (WebCore::MediaSession::positionOverridden): 39 * Modules/mediasession/MediaSession.h: 40 * html/HTMLMediaElement.cpp: 41 (WebCore::HTMLMediaElement::parseAttribute): 42 (WebCore::HTMLMediaElement::removedFromAncestor): 43 (WebCore::HTMLMediaElement::mediaLoadingFailed): 44 (WebCore::HTMLMediaElement::setReadyState): 45 (WebCore::HTMLMediaElement::finishSeek): 46 (WebCore::HTMLMediaElement::clearMediaPlayer): 47 * html/MediaElementSession.cpp: 48 (WebCore::MediaElementSession::clientWillBeginPlayback): 49 (WebCore::MediaElementSession::clientWillPausePlayback): 50 (WebCore::MediaElementSession::nowPlayingInfo const): 51 (WebCore::MediaElementSession::metadataChanged): 52 (WebCore::MediaElementSession::positionStateChanged): 53 (WebCore::MediaElementSession::clientCharacteristicsChanged): 54 * html/MediaElementSession.h: 55 * platform/audio/NowPlayingInfo.h: 56 (WebCore::NowPlayingInfo::operator== const): 57 (WebCore::NowPlayingInfo::encode const): 58 (WebCore::NowPlayingInfo::decode): 59 * platform/audio/PlatformMediaSession.cpp: 60 (WebCore::PlatformMediaSession::clientCharacteristicsChanged): 61 * platform/audio/PlatformMediaSession.h: 62 * platform/audio/PlatformMediaSessionManager.h: 63 (WebCore::PlatformMediaSessionManager::clientCharacteristicsChanged): 64 * platform/audio/cocoa/MediaSessionManagerCocoa.h: 65 * platform/audio/cocoa/MediaSessionManagerCocoa.mm: 66 (WebCore::MediaSessionManagerCocoa::clientCharacteristicsChanged): 67 (WebCore::MediaSessionManagerCocoa::setNowPlayingInfo): 68 1 69 2022-04-26 Elliott Williams <emw@apple.com> 2 70 -
trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp
r287138 r293488 229 229 ALWAYS_LOG(LOGIDENTIFIER, state); 230 230 231 auto currentPosition = this->currentPosition(); 232 if (m_positionState && currentPosition) { 233 m_positionState->position = *currentPosition; 234 m_timeAtLastPositionUpdate = MonotonicTime::now(); 235 } 231 updateReportedPosition(); 232 236 233 m_playbackState = state; 237 234 notifyPlaybackStateObservers(); … … 397 394 } 398 395 396 void MediaSession::updateReportedPosition() 397 { 398 auto currentPosition = this->currentPosition(); 399 if (m_positionState && currentPosition) { 400 m_lastReportedPosition = m_positionState->position = *currentPosition; 401 m_timeAtLastPositionUpdate = MonotonicTime::now(); 402 } 403 } 404 405 void MediaSession::willBeginPlayback() 406 { 407 updateReportedPosition(); 408 m_playbackState = MediaSessionPlaybackState::Playing; 409 notifyPositionStateObservers(); 410 } 411 412 void MediaSession::willPausePlayback() 413 { 414 updateReportedPosition(); 415 m_playbackState = MediaSessionPlaybackState::Paused; 416 notifyPositionStateObservers(); 417 } 418 399 419 #if ENABLE(MEDIA_SESSION_COORDINATOR) 400 420 void MediaSession::notifyReadyStateObservers() -
trunk/Source/WebCore/Modules/mediasession/MediaSession.h
r284857 r293488 72 72 73 73 WEBCORE_EXPORT std::optional<double> currentPosition() const; 74 void willBeginPlayback(); 75 void willPausePlayback(); 74 76 75 77 Document* document() const; … … 120 122 121 123 const void* logIdentifier() const { return m_logIdentifier; } 124 125 void updateReportedPosition(); 122 126 123 127 void forEachObserver(const Function<void(Observer&)>&); -
trunk/Source/WebCore/html/HTMLMediaElement.cpp
r293484 r293488 790 790 } else if (name == titleAttr) { 791 791 if (m_mediaSession) 792 m_mediaSession->clientCharacteristicsChanged( );792 m_mediaSession->clientCharacteristicsChanged(false); 793 793 } 794 794 else … … 894 894 895 895 if (m_mediaSession) 896 m_mediaSession->clientCharacteristicsChanged( );896 m_mediaSession->clientCharacteristicsChanged(false); 897 897 898 898 HTMLElement::removedFromAncestor(removalType, oldParentOfRemovedTree); … … 2353 2353 logMediaLoadRequest(document().page(), String(), convertEnumerationToString(error), false); 2354 2354 2355 mediaSession().clientCharacteristicsChanged( );2355 mediaSession().clientCharacteristicsChanged(false); 2356 2356 #if ENABLE(WIRELESS_PLAYBACK_TARGET) 2357 2357 if (!m_hasPlaybackTargetAvailabilityListeners) … … 2578 2578 #endif 2579 2579 2580 mediaSession().clientCharacteristicsChanged( );2580 mediaSession().clientCharacteristicsChanged(false); 2581 2581 2582 2582 // As the spec only mentiones HAVE_METADATA, run the later … … 3320 3320 3321 3321 if (m_mediaSession) 3322 m_mediaSession->clientCharacteristicsChanged( );3322 m_mediaSession->clientCharacteristicsChanged(true); 3323 3323 3324 3324 #if ENABLE(MEDIA_SOURCE) … … 5919 5919 queueTaskKeepingObjectAlive(*this, TaskSource::MediaElement, [this] { 5920 5920 if (m_mediaSession) { 5921 m_mediaSession->clientCharacteristicsChanged( );5921 m_mediaSession->clientCharacteristicsChanged(false); 5922 5922 m_mediaSession->canProduceAudioChanged(); 5923 5923 } -
trunk/Source/WebCore/html/MediaElementSession.cpp
r293484 r293488 235 235 m_elementIsHiddenBecauseItWasRemovedFromDOM = false; 236 236 updateClientDataBuffering(); 237 238 #if ENABLE(MEDIA_SESSION) 239 if (auto* session = mediaSession()) 240 session->willBeginPlayback(); 241 #endif 242 237 243 return true; 238 244 } … … 244 250 245 251 updateClientDataBuffering(); 252 253 #if ENABLE(MEDIA_SESSION) 254 if (auto* session = mediaSession()) 255 session->willPausePlayback(); 256 #endif 257 246 258 return true; 247 259 } … … 1177 1189 bool isPlaying = state() == PlatformMediaSession::Playing; 1178 1190 bool supportsSeeking = m_element.supportsSeeking(); 1191 double rate = 1.0; 1179 1192 double duration = supportsSeeking ? m_element.duration() : MediaPlayer::invalidTime(); 1180 1193 double currentTime = m_element.currentTime(); … … 1184 1197 #if ENABLE(MEDIA_SESSION) 1185 1198 auto* session = mediaSession(); 1199 auto positionState = session ? session->positionState() : std::nullopt; 1200 auto currentPosition = session ? session->currentPosition() : std::nullopt; 1201 if (positionState) { 1202 duration = positionState->duration; 1203 rate = positionState->playbackRate; 1204 } 1205 if (currentPosition) 1206 currentTime = *currentPosition; 1186 1207 auto* sessionMetadata = session ? session->metadata() : nullptr; 1187 1208 if (sessionMetadata) { … … 1191 1212 artwork = NowPlayingInfoArtwork { sessionMetadata->artworkSrc(), sessionMetadata->artworkImage()->mimeType(), sessionMetadata->artworkImage()->data() }; 1192 1213 } 1193 return NowPlayingInfo { sessionMetadata->title(), sessionMetadata->artist(), sessionMetadata->album(), m_element.sourceApplicationIdentifier(), duration, currentTime, supportsSeeking, m_element.mediaUniqueIdentifier(), isPlaying, allowsNowPlayingControlsVisibility, WTFMove(artwork) };1194 } 1195 #endif 1196 1197 return NowPlayingInfo { m_element.mediaSessionTitle(), emptyString(), emptyString(), m_element.sourceApplicationIdentifier(), duration, currentTime, supportsSeeking, m_element.mediaUniqueIdentifier(), isPlaying, allowsNowPlayingControlsVisibility, { }};1214 return NowPlayingInfo { sessionMetadata->title(), sessionMetadata->artist(), sessionMetadata->album(), m_element.sourceApplicationIdentifier(), duration, currentTime, rate, supportsSeeking, m_element.mediaUniqueIdentifier(), isPlaying, allowsNowPlayingControlsVisibility, WTFMove(artwork) }; 1215 } 1216 #endif 1217 1218 return NowPlayingInfo { m_element.mediaSessionTitle(), emptyString(), emptyString(), m_element.sourceApplicationIdentifier(), duration, currentTime, rate, supportsSeeking, m_element.mediaUniqueIdentifier(), isPlaying, allowsNowPlayingControlsVisibility, { } }; 1198 1219 } 1199 1220 … … 1300 1321 void MediaElementSession::metadataChanged(const RefPtr<MediaMetadata>&) 1301 1322 { 1302 clientCharacteristicsChanged(); 1303 } 1304 1305 void MediaElementSession::positionStateChanged(const std::optional<MediaPositionState>&) { } 1323 clientCharacteristicsChanged(false); 1324 } 1325 1326 void MediaElementSession::positionStateChanged(const std::optional<MediaPositionState>&) 1327 { 1328 clientCharacteristicsChanged(false); 1329 } 1306 1330 1307 1331 void MediaElementSession::playbackStateChanged(MediaSessionPlaybackState) { } … … 1309 1333 void MediaElementSession::actionHandlersChanged() { } 1310 1334 1335 void MediaElementSession::clientCharacteristicsChanged(bool positionChanged) 1336 { 1337 #if ENABLE(MEDIA_SESSION) 1338 auto* session = mediaSession(); 1339 if (positionChanged && session) { 1340 auto positionState = session->positionState(); 1341 if (positionState) 1342 session->setPositionState(MediaPositionState { positionState->duration, positionState->playbackRate, m_element.currentTime() }); 1343 } 1344 #endif 1345 PlatformMediaSession::clientCharacteristicsChanged(positionChanged); 1346 } 1347 1311 1348 } 1312 1349 -
trunk/Source/WebCore/html/MediaElementSession.h
r284080 r293488 71 71 bool clientWillBeginPlayback() final; 72 72 bool clientWillPausePlayback() final; 73 void clientCharacteristicsChanged(bool) final; 73 74 74 75 void visibilityChanged(); -
trunk/Source/WebCore/platform/audio/NowPlayingInfo.h
r287021 r293488 82 82 double duration { 0 }; 83 83 double currentTime { 0 }; 84 double rate { 1.0 }; 84 85 bool supportsSeeking { false }; 85 86 MediaUniqueIdentifier uniqueIdentifier; … … 96 97 && duration == other.duration 97 98 && currentTime == other.currentTime 99 && rate == other.rate 98 100 && supportsSeeking == other.supportsSeeking 99 101 && uniqueIdentifier == other.uniqueIdentifier … … 114 116 template<class Encoder> inline void NowPlayingInfo::encode(Encoder& encoder) const 115 117 { 116 encoder << title << artist << album << sourceApplicationIdentifier << duration << currentTime << supportsSeeking << uniqueIdentifier << isPlaying << allowsNowPlayingControlsVisibility << artwork;118 encoder << title << artist << album << sourceApplicationIdentifier << duration << currentTime << rate << supportsSeeking << uniqueIdentifier << isPlaying << allowsNowPlayingControlsVisibility << artwork; 117 119 } 118 120 … … 143 145 return { }; 144 146 147 double rate; 148 if (!decoder.decode(rate)) 149 return { }; 150 145 151 bool supportsSeeking; 146 152 if (!decoder.decode(supportsSeeking)) … … 163 169 return { }; 164 170 165 return NowPlayingInfo { WTFMove(title), WTFMove(artist), WTFMove(album), WTFMove(sourceApplicationIdentifier), duration, currentTime, supportsSeeking, uniqueIdentifier, isPlaying, allowsNowPlayingControlsVisibility, WTFMove(artwork) };171 return NowPlayingInfo { WTFMove(title), WTFMove(artist), WTFMove(album), WTFMove(sourceApplicationIdentifier), duration, currentTime, rate, supportsSeeking, uniqueIdentifier, isPlaying, allowsNowPlayingControlsVisibility, WTFMove(artwork) }; 166 172 } 167 173 -
trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp
r292563 r293488 376 376 } 377 377 378 void PlatformMediaSession::clientCharacteristicsChanged( )379 { 380 PlatformMediaSessionManager::sharedManager().clientCharacteristicsChanged(*this );378 void PlatformMediaSession::clientCharacteristicsChanged(bool positionChanged) 379 { 380 PlatformMediaSessionManager::sharedManager().clientCharacteristicsChanged(*this, positionChanged); 381 381 } 382 382 -
trunk/Source/WebCore/platform/audio/PlatformMediaSession.h
r292563 r293488 103 103 }; 104 104 105 v oid clientCharacteristicsChanged();105 virtual void clientCharacteristicsChanged(bool); 106 106 107 107 void beginInterruption(InterruptionType); -
trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h
r291759 r293488 132 132 virtual void sessionStateChanged(PlatformMediaSession&); 133 133 virtual void sessionDidEndRemoteScrubbing(PlatformMediaSession&) { }; 134 virtual void clientCharacteristicsChanged(PlatformMediaSession& ) { }134 virtual void clientCharacteristicsChanged(PlatformMediaSession&, bool) { } 135 135 virtual void sessionCanProduceAudioChanged(); 136 136 -
trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h
r291759 r293488 88 88 void sessionWillEndPlayback(PlatformMediaSession&, DelayCallingUpdateNowPlaying) override; 89 89 void sessionDidEndRemoteScrubbing(PlatformMediaSession&) final; 90 void clientCharacteristicsChanged(PlatformMediaSession& ) final;90 void clientCharacteristicsChanged(PlatformMediaSession&, bool) final; 91 91 void sessionCanProduceAudioChanged() final; 92 92 -
trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm
r292563 r293488 310 310 } 311 311 312 void MediaSessionManagerCocoa::clientCharacteristicsChanged(PlatformMediaSession& session )312 void MediaSessionManagerCocoa::clientCharacteristicsChanged(PlatformMediaSession& session, bool) 313 313 { 314 314 ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier()); … … 377 377 } 378 378 379 double rate = nowPlayingInfo.isPlaying ? 1: 0;379 double rate = nowPlayingInfo.isPlaying ? nowPlayingInfo.rate : 0; 380 380 auto cfRate = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &rate)); 381 381 CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoPlaybackRate, cfRate.get()); -
trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp
r285654 r293488 228 228 } 229 229 230 void MediaSessionManagerGLib::clientCharacteristicsChanged(PlatformMediaSession& platformSession )230 void MediaSessionManagerGLib::clientCharacteristicsChanged(PlatformMediaSession& platformSession, bool) 231 231 { 232 232 ALWAYS_LOG(LOGIDENTIFIER, platformSession.logIdentifier()); -
trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.h
r283437 r293488 66 66 void sessionStateChanged(PlatformMediaSession&) override; 67 67 void sessionDidEndRemoteScrubbing(PlatformMediaSession&) final; 68 void clientCharacteristicsChanged(PlatformMediaSession& ) final;68 void clientCharacteristicsChanged(PlatformMediaSession&, bool) final; 69 69 void sessionCanProduceAudioChanged() final; 70 70
Note: See TracChangeset
for help on using the changeset viewer.