Diff
Modified: trunk/Source/WebCore/ChangeLog (165627 => 165628)
--- trunk/Source/WebCore/ChangeLog 2014-03-14 17:21:35 UTC (rev 165627)
+++ trunk/Source/WebCore/ChangeLog 2014-03-14 17:21:57 UTC (rev 165628)
@@ -1,3 +1,28 @@
+2014-03-07 Jer Noble <jer.no...@apple.com>
+
+ Add Remote Control command support to HTLMediaElement
+ https://bugs.webkit.org/show_bug.cgi?id=129926
+
+ Reviewed by Eric Carlson.
+
+ Support the new MediaSession remote control commands by pulling in code from
+ MediaControlElementTypes to control scanning.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement):
+ * html/HTMLMediaElement.h:
+ * html/MediaController.cpp:
+ (MediaController::beginScanning): Moved from MediaControlElementTypes.
+ (MediaController::endScanning): Ditto.
+ * html/MediaController.h:
+ * html/MediaControllerInterface.h:
+
+ Remove all the scanning code from MediaControlSeekButtonElement.
+ * html/shadow/MediaControlElementTypes.cpp:
+ (WebCore::MediaControlSeekButtonElement::MediaControlSeekButtonElement):
+ (WebCore::MediaControlSeekButtonElement::setActive):
+ * html/shadow/MediaControlElementTypes.h:
+
2014-03-14 Krzysztof Czech <k.cz...@samsung.com>
Move WebSpeech code to use std::unique_ptr
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (165627 => 165628)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2014-03-14 17:21:35 UTC (rev 165627)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2014-03-14 17:21:57 UTC (rev 165628)
@@ -146,6 +146,11 @@
namespace WebCore {
+static const double SeekRepeatDelay = 0.1;
+static const double SeekTime = 0.2;
+static const double ScanRepeatDelay = 1.5;
+static const double ScanMaximumRate = 8;
+
static void setFlags(unsigned& value, unsigned flags)
{
value |= flags;
@@ -261,6 +266,7 @@
, m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
, m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
, m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
+ , m_scanTimer(this, &HTMLMediaElement::scanTimerFired)
, m_playedTimeRanges()
, m_asyncEventQueue(*this)
, m_playbackRate(1.0f)
@@ -294,6 +300,9 @@
, m_fragmentStartTime(MediaPlayer::invalidTime())
, m_fragmentEndTime(MediaPlayer::invalidTime())
, m_pendingActionFlags(0)
+ , m_actionAfterScan(Nothing)
+ , m_scanType(Scan)
+ , m_scanDirection(Forward)
, m_playing(false)
, m_isWaitingUntilMediaCanStart(false)
, m_shouldDelayLoadEvent(false)
@@ -3006,6 +3015,56 @@
setPausedInternal(false);
}
+void HTMLMediaElement::beginScanning(ScanDirection direction)
+{
+ m_scanType = supportsScanning() ? Scan : Seek;
+ m_scanDirection = direction;
+
+ if (m_scanType == Seek) {
+ // Scanning by seeking requires the video to be paused during scanning.
+ m_actionAfterScan = paused() ? Nothing : Play;
+ pause();
+ } else {
+ // Scanning by scanning requires the video to be playing during scanninging.
+ m_actionAfterScan = paused() ? Pause : Nothing;
+ play();
+ setPlaybackRate(nextScanRate());
+ }
+
+ m_scanTimer.start(0, m_scanType == Seek ? SeekRepeatDelay : ScanRepeatDelay);
+}
+
+void HTMLMediaElement::endScanning()
+{
+ if (m_scanType == Scan)
+ setPlaybackRate(defaultPlaybackRate());
+
+ if (m_actionAfterScan == Play)
+ play();
+ else if (m_actionAfterScan == Pause)
+ pause();
+
+ if (m_scanTimer.isActive())
+ m_scanTimer.stop();
+}
+
+double HTMLMediaElement::nextScanRate()
+{
+ double rate = std::min(ScanMaximumRate, fabs(playbackRate() * 2));
+ if (m_scanDirection == Backward)
+ rate *= -1;
+ return rate;
+}
+
+void HTMLMediaElement::scanTimerFired(Timer<HTMLMediaElement>&)
+{
+ if (m_scanType == Seek) {
+ double seekTime = m_scanDirection == Forward ? SeekTime : -SeekTime;
+ setCurrentTime(currentTime() + seekTime);
+ } else
+ setPlaybackRate(nextScanRate());
+}
+
// The spec says to fire periodic timeupdate events (those sent while playing) every
// "15 to 250ms", we choose the slowest frequency
static const double maxTimeupdateEventFrequency = 0.25;
@@ -5889,8 +5948,29 @@
void HTMLMediaElement::didReceiveRemoteControlCommand(MediaSession::RemoteControlCommandType command)
{
- // FIXME(129926): Add Remote Control support to HTMLMediaElement
- UNUSED_PARAM(command);
+ switch (command) {
+ case MediaSession::PlayCommand:
+ play();
+ break;
+ case MediaSession::PauseCommand:
+ pause();
+ break;
+ case MediaSession::TogglePlayPauseCommand:
+ canPlay() ? play() : pause();
+ break;
+ case MediaSession::BeginSeekingBackwardCommand:
+ beginScanning(Backward);
+ break;
+ case MediaSession::BeginSeekingForwardCommand:
+ beginScanning(Forward);
+ break;
+ case MediaSession::EndSeekingBackwardCommand:
+ case MediaSession::EndSeekingForwardCommand:
+ endScanning();
+ break;
+ default:
+ { } // Do nothing
+ }
}
}
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (165627 => 165628)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2014-03-14 17:21:35 UTC (rev 165627)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2014-03-14 17:21:57 UTC (rev 165628)
@@ -249,7 +249,11 @@
void togglePlayState();
virtual void beginScrubbing() override;
virtual void endScrubbing() override;
-
+
+ virtual void beginScanning(ScanDirection) override;
+ virtual void endScanning() override;
+ double nextScanRate();
+
virtual bool canPlay() const override;
double percentLoaded() const;
@@ -583,6 +587,7 @@
void loadTimerFired(Timer<HTMLMediaElement>&);
void progressEventTimerFired(Timer<HTMLMediaElement>&);
void playbackProgressTimerFired(Timer<HTMLMediaElement>&);
+ void scanTimerFired(Timer<HTMLMediaElement>&);
void startPlaybackProgressTimer();
void startProgressEventTimer();
void stopPeriodicTimers();
@@ -703,6 +708,7 @@
Timer<HTMLMediaElement> m_loadTimer;
Timer<HTMLMediaElement> m_progressEventTimer;
Timer<HTMLMediaElement> m_playbackProgressTimer;
+ Timer<HTMLMediaElement> m_scanTimer;
RefPtr<TimeRanges> m_playedTimeRanges;
GenericEventQueue m_asyncEventQueue;
@@ -769,6 +775,15 @@
typedef unsigned PendingActionFlags;
PendingActionFlags m_pendingActionFlags;
+ enum ActionAfterScanType {
+ Nothing, Play, Pause
+ };
+ ActionAfterScanType m_actionAfterScan;
+
+ enum ScanType { Seek, Scan };
+ ScanType m_scanType;
+ ScanDirection m_scanDirection;
+
bool m_playing : 1;
bool m_isWaitingUntilMediaCanStart : 1;
bool m_shouldDelayLoadEvent : 1;
Modified: trunk/Source/WebCore/html/MediaController.cpp (165627 => 165628)
--- trunk/Source/WebCore/html/MediaController.cpp 2014-03-14 17:21:35 UTC (rev 165627)
+++ trunk/Source/WebCore/html/MediaController.cpp 2014-03-14 17:21:57 UTC (rev 165628)
@@ -612,6 +612,18 @@
m_clock->start();
}
+void MediaController::beginScanning(ScanDirection direction)
+{
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->beginScanning(direction);
+}
+
+void MediaController::endScanning()
+{
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->endScanning();
+}
+
bool MediaController::canPlay() const
{
if (m_paused)
Modified: trunk/Source/WebCore/html/MediaController.h (165627 => 165628)
--- trunk/Source/WebCore/html/MediaController.h 2014-03-14 17:21:35 UTC (rev 165627)
+++ trunk/Source/WebCore/html/MediaController.h 2014-03-14 17:21:57 UTC (rev 165628)
@@ -98,6 +98,8 @@
virtual void beginScrubbing() override;
virtual void endScrubbing() override;
+ virtual void beginScanning(ScanDirection) override;
+ virtual void endScanning() override;
virtual bool canPlay() const override;
Modified: trunk/Source/WebCore/html/MediaControllerInterface.h (165627 => 165628)
--- trunk/Source/WebCore/html/MediaControllerInterface.h 2014-03-14 17:21:35 UTC (rev 165627)
+++ trunk/Source/WebCore/html/MediaControllerInterface.h 2014-03-14 17:21:57 UTC (rev 165628)
@@ -84,6 +84,13 @@
virtual void beginScrubbing() = 0;
virtual void endScrubbing() = 0;
+ enum ScanDirection {
+ Backward,
+ Forward,
+ };
+ virtual void beginScanning(ScanDirection) = 0;
+ virtual void endScanning() = 0;
+
virtual bool canPlay() const = 0;
virtual bool isLiveStream() const = 0;
Modified: trunk/Source/WebCore/html/shadow/MediaControlElementTypes.cpp (165627 => 165628)
--- trunk/Source/WebCore/html/shadow/MediaControlElementTypes.cpp 2014-03-14 17:21:35 UTC (rev 165627)
+++ trunk/Source/WebCore/html/shadow/MediaControlElementTypes.cpp 2014-03-14 17:21:57 UTC (rev 165628)
@@ -46,12 +46,6 @@
class Event;
-// FIXME: These constants may need to be tweaked to better match the seeking in the QuickTime plug-in.
-static const double cSkipRepeatDelay = 0.1;
-static const double cSkipTime = 0.2;
-static const double cScanRepeatDelay = 1.5;
-static const double cScanMaximumRate = 8;
-
HTMLMediaElement* parentMediaElement(Node* node)
{
if (!node)
@@ -168,9 +162,6 @@
MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document& document, MediaControlElementType displayType)
: MediaControlInputElement(document, displayType)
- , m_actionOnStop(Nothing)
- , m_seekType(Skip)
- , m_seekTimer(this, &MediaControlSeekButtonElement::seekTimerFired)
{
}
@@ -188,62 +179,13 @@
return;
if (flag)
- startTimer();
+ mediaController()->beginScanning(isForwardButton() ? MediaControllerInterface::Forward : MediaControllerInterface::Backward);
else
- stopTimer();
+ mediaController()->endScanning();
MediaControlInputElement::setActive(flag, pause);
}
-void MediaControlSeekButtonElement::startTimer()
-{
- m_seekType = mediaController()->supportsScanning() ? Scan : Skip;
-
- if (m_seekType == Skip) {
- // Seeking by skipping requires the video to be paused during seeking.
- m_actionOnStop = mediaController()->paused() ? Nothing : Play;
- mediaController()->pause();
- } else {
- // Seeking by scanning requires the video to be playing during seeking.
- m_actionOnStop = mediaController()->paused() ? Pause : Nothing;
- mediaController()->play();
- mediaController()->setPlaybackRate(nextRate());
- }
-
- m_seekTimer.start(0, m_seekType == Skip ? cSkipRepeatDelay : cScanRepeatDelay);
-}
-
-void MediaControlSeekButtonElement::stopTimer()
-{
- if (m_seekType == Scan)
- mediaController()->setPlaybackRate(mediaController()->defaultPlaybackRate());
-
- if (m_actionOnStop == Play)
- mediaController()->play();
- else if (m_actionOnStop == Pause)
- mediaController()->pause();
-
- if (m_seekTimer.isActive())
- m_seekTimer.stop();
-}
-
-double MediaControlSeekButtonElement::nextRate() const
-{
- double rate = std::min(cScanMaximumRate, fabs(mediaController()->playbackRate() * 2));
- if (!isForwardButton())
- rate *= -1;
- return rate;
-}
-
-void MediaControlSeekButtonElement::seekTimerFired(Timer<MediaControlSeekButtonElement>&)
-{
- if (m_seekType == Skip) {
- double skipTime = isForwardButton() ? cSkipTime : -cSkipTime;
- mediaController()->setCurrentTime(mediaController()->currentTime() + skipTime);
- } else
- mediaController()->setPlaybackRate(nextRate());
-}
-
// ----------------------------
MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document)
Modified: trunk/Source/WebCore/html/shadow/MediaControlElementTypes.h (165627 => 165628)
--- trunk/Source/WebCore/html/shadow/MediaControlElementTypes.h 2014-03-14 17:21:35 UTC (rev 165627)
+++ trunk/Source/WebCore/html/shadow/MediaControlElementTypes.h 2014-03-14 17:21:57 UTC (rev 165628)
@@ -170,17 +170,6 @@
private:
virtual void setActive(bool /*flag*/ = true, bool /*pause*/ = false) override final;
-
- void startTimer();
- void stopTimer();
- double nextRate() const;
- void seekTimerFired(Timer<MediaControlSeekButtonElement>&);
-
- enum ActionType { Nothing, Play, Pause };
- ActionType m_actionOnStop;
- enum SeekType { Skip, Scan };
- SeekType m_seekType;
- Timer<MediaControlSeekButtonElement> m_seekTimer;
};
// ----------------------------