Changeset 291629 in webkit


Ignore:
Timestamp:
Mar 22, 2022 10:42:01 AM (4 months ago)
Author:
jer.noble@apple.com
Message:

YouTube.com - Clicking anywhere on the progress bar pauses the video
https://bugs.webkit.org/show_bug.cgi?id=237750
<rdar://problem/90364846>

Reviewed by Eric Carlson.

Source/WebCore:

Test: media/media-source/media-source-unexpected-pause.html

When calling play() or pause() on a MediaPlayerPrivateMediaSourceAVFObjC, the object will
respond by calling m_player->playbackStateChanged(), which will in turn call
HTMLMediaElement::mediaPlayerPlaybackStateChanged() with the new state. However, HTMLMediaElement
expects this to be called only for unanticipated state changes, not expected state changes. And
when that method is called and the reported state does not match the element's own expected state,
the element calls its own play() or pause() function to update its own state to match the player's.
And because MediaPlayerPrivateMediaSourceAVFObjC calls this method on the next run loop, there is
an opportunity for those states to get out of sync, which happens when YouTube responds to a tap
in its timeline.

Remove the unnecessary "call on next run loop" behavior of MediaPlayerPrivateMediaSourceAVFObjC::
play() and ::pause(). Also, remove the unnecessary notification that the play state has changed. In
the future, this can be accomplished by adding a callback parameter to MediaPlayer::play() rather than
relying on a state change notification.

  • platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:

(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::play):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::playInternal):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::pause):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::pauseInternal):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::playAtHostTime):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::pauseAtHostTime):

LayoutTests:

  • media/media-source/media-source-unexpected-pause-expected.txt: Added.
  • media/media-source/media-source-unexpected-pause.html: Added.
Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r291623 r291629  
     12022-03-22  Jer Noble  <jer.noble@apple.com>
     2
     3        YouTube.com - Clicking anywhere on the progress bar pauses the video
     4        https://bugs.webkit.org/show_bug.cgi?id=237750
     5        <rdar://problem/90364846>
     6
     7        Reviewed by Eric Carlson.
     8
     9        * media/media-source/media-source-unexpected-pause-expected.txt: Added.
     10        * media/media-source/media-source-unexpected-pause.html: Added.
     11
    1122022-03-22  Ricky Mondello  <rmondello@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r291624 r291629  
     12022-03-22  Jer Noble  <jer.noble@apple.com>
     2
     3        YouTube.com - Clicking anywhere on the progress bar pauses the video
     4        https://bugs.webkit.org/show_bug.cgi?id=237750
     5        <rdar://problem/90364846>
     6
     7        Reviewed by Eric Carlson.
     8
     9        Test: media/media-source/media-source-unexpected-pause.html
     10
     11        When calling play() or pause() on a MediaPlayerPrivateMediaSourceAVFObjC, the object will
     12        respond by calling m_player->playbackStateChanged(), which will in turn call
     13        HTMLMediaElement::mediaPlayerPlaybackStateChanged() with the new state. However, HTMLMediaElement
     14        expects this to be called only for unanticipated state changes, not expected state changes. And
     15        when that method is called and the reported state does not match the element's own expected state,
     16        the element calls its own play() or pause() function to update its own state to match the player's.
     17        And because MediaPlayerPrivateMediaSourceAVFObjC calls this method on the next run loop, there is
     18        an opportunity for those states to get out of sync, which happens when YouTube responds to a tap
     19        in its timeline.
     20
     21        Remove the unnecessary "call on next run loop" behavior of MediaPlayerPrivateMediaSourceAVFObjC::
     22        play() and ::pause(). Also, remove the unnecessary notification that the play state has changed. In
     23        the future, this can be accomplished by adding a callback parameter to MediaPlayer::play() rather than
     24        relying on a state change notification.
     25
     26        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
     27        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::play):
     28        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::playInternal):
     29        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::pause):
     30        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::pauseInternal):
     31        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::playAtHostTime):
     32        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::pauseAtHostTime):
     33
    1342022-03-22  J Pascoe  <j_pascoe@apple.com>
    235
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm

    r291611 r291629  
    315315{
    316316    ALWAYS_LOG(LOGIDENTIFIER);
    317     callOnMainThread([weakThis = WeakPtr { *this }] {
    318         if (!weakThis)
    319             return;
    320         weakThis.get()->playInternal();
    321     });
     317    playInternal();
    322318}
    323319
     
    353349    [m_synchronizer setRate:m_rate];
    354350#endif
    355 
    356     m_player->playbackStateChanged();
    357351}
    358352
     
    360354{
    361355    ALWAYS_LOG(LOGIDENTIFIER);
    362     callOnMainThread([weakThis = WeakPtr { *this }] {
    363         if (!weakThis)
    364             return;
    365         weakThis.get()->pauseInternal();
    366     });
     356    pauseInternal();
    367357}
    368358
     
    385375    [m_synchronizer setRate:0];
    386376#endif
    387 
    388     m_player->playbackStateChanged();
    389377}
    390378
     
    480468{
    481469    ALWAYS_LOG(LOGIDENTIFIER);
    482     callOnMainThread([weakThis = WeakPtr { *this }, time = time] {
    483         if (!weakThis)
    484             return;
    485         weakThis.get()->playInternal(time);
    486     });
     470    playInternal(time);
    487471    return true;
    488472}
     
    491475{
    492476    ALWAYS_LOG(LOGIDENTIFIER);
    493     callOnMainThread([weakThis = WeakPtr { *this }, time = time] {
    494         if (!weakThis)
    495             return;
    496         weakThis.get()->pauseInternal(time);
    497     });
     477    pauseInternal(time);
    498478    return true;
    499479}
Note: See TracChangeset for help on using the changeset viewer.