diff --git a/Libraries/LibWeb/HTML/HTMLMediaElement.cpp b/Libraries/LibWeb/HTML/HTMLMediaElement.cpp
index 298181e9170..99a6cbc03d2 100644
--- a/Libraries/LibWeb/HTML/HTMLMediaElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLMediaElement.cpp
@@ -570,7 +570,8 @@ WebIDL::ExceptionOr HTMLMediaElement::load_element()
set_duration(NAN);
}
- // FIXME: 7. Set the playbackRate attribute to the value of the defaultPlaybackRate attribute.
+ // 7. Set the playbackRate attribute to the value of the defaultPlaybackRate attribute.
+ TRY(set_playback_rate(m_default_playback_rate));
// 8. Set the error attribute to null and the can autoplay flag to true.
m_error = nullptr;
@@ -1650,6 +1651,48 @@ void HTMLMediaElement::set_paused(bool paused)
set_needs_style_update(true);
}
+// https://html.spec.whatwg.org/multipage/media.html#dom-media-defaultplaybackrate
+void HTMLMediaElement::set_default_playback_rate(double new_value)
+{
+ // When the defaultPlaybackRate or playbackRate attributes change value (either by being set by script or by being changed directly by the user agent, e.g. in response to user
+ // control) the user agent must queue a media element task given the media element to fire an event named ratechange at the media element.
+ if (m_default_playback_rate != new_value) {
+ queue_a_media_element_task([this] {
+ dispatch_event(DOM::Event::create(realm(), HTML::EventNames::ratechange));
+ });
+ }
+
+ // on setting the attribute must be set to the new value.
+ m_default_playback_rate = new_value;
+}
+
+// https://html.spec.whatwg.org/multipage/media.html#dom-media-playbackrate
+WebIDL::ExceptionOr HTMLMediaElement::set_playback_rate(double new_value)
+{
+ // on setting, the user agent must follow these steps:
+
+ // 1. If the given value is not supported by the user agent, then throw a "NotSupportedError" DOMException.
+ // FIXME: We need to support playback rates other than 1 for this to be even remotely useful.
+ if (new_value != 1.0)
+ return WebIDL::NotSupportedError::create(realm(), "Playback rates other than 1 are not supported."_string);
+
+ // When the defaultPlaybackRate or playbackRate attributes change value (either by being set by script or by being changed directly by the user agent, e.g. in response to user
+ // control) the user agent must queue a media element task given the media element to fire an event named ratechange at the media element.
+ if (m_playback_rate != new_value) {
+ queue_a_media_element_task([this] {
+ dispatch_event(DOM::Event::create(realm(), HTML::EventNames::ratechange));
+ });
+ }
+
+ // 2. Set playbackRate to the new value, and if the element is potentially playing, change the playback speed.
+ m_playback_rate = new_value;
+ if (potentially_playing()) {
+ // FIXME: Do this once playback speeds other than 1 are supported.
+ }
+
+ return {};
+}
+
// https://html.spec.whatwg.org/multipage/media.html#blocked-media-element
bool HTMLMediaElement::blocked() const
{
diff --git a/Libraries/LibWeb/HTML/HTMLMediaElement.h b/Libraries/LibWeb/HTML/HTMLMediaElement.h
index c64d5cc7b31..9923331f585 100644
--- a/Libraries/LibWeb/HTML/HTMLMediaElement.h
+++ b/Libraries/LibWeb/HTML/HTMLMediaElement.h
@@ -109,6 +109,12 @@ public:
double volume() const { return m_volume; }
WebIDL::ExceptionOr set_volume(double);
+ double default_playback_rate() const { return m_default_playback_rate; }
+ void set_default_playback_rate(double);
+
+ double playback_rate() const { return m_playback_rate; }
+ WebIDL::ExceptionOr set_playback_rate(double);
+
bool muted() const { return m_muted; }
void set_muted(bool);
@@ -266,6 +272,12 @@ private:
// https://html.spec.whatwg.org/multipage/media.html#dom-media-paused
bool m_paused { true };
+ // https://html.spec.whatwg.org/multipage/media.html#dom-media-defaultplaybackrate
+ double m_default_playback_rate { 1.0 };
+
+ // https://html.spec.whatwg.org/multipage/media.html#dom-media-playbackrate
+ double m_playback_rate { 1.0 };
+
// https://html.spec.whatwg.org/multipage/media.html#dom-media-volume
double m_volume { 1.0 };
diff --git a/Libraries/LibWeb/HTML/HTMLMediaElement.idl b/Libraries/LibWeb/HTML/HTMLMediaElement.idl
index 8e1bde48900..e4d58c251c3 100644
--- a/Libraries/LibWeb/HTML/HTMLMediaElement.idl
+++ b/Libraries/LibWeb/HTML/HTMLMediaElement.idl
@@ -59,8 +59,8 @@ interface HTMLMediaElement : HTMLElement {
readonly attribute unrestricted double duration;
[FIXME] object getStartDate();
readonly attribute boolean paused;
- [FIXME] attribute double defaultPlaybackRate;
- [FIXME] attribute double playbackRate;
+ attribute double defaultPlaybackRate;
+ attribute double playbackRate;
[FIXME] attribute boolean preservesPitch;
[FIXME] readonly attribute TimeRanges played;
[FIXME] readonly attribute TimeRanges seekable;
diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.txt
new file mode 100644
index 00000000000..276aca28c21
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.txt
@@ -0,0 +1,12 @@
+Harness status: OK
+
+Found 7 tests
+
+7 Pass
+Pass playbackRate initial value
+Pass playbackRate set to small positive value
+Pass playbackRate set to large positive value
+Pass playbackRate set to small negative value
+Pass playbackRate set to large negative value
+Pass playbackRate set to 0
+Pass playbackRate set to -1
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html
new file mode 100644
index 00000000000..f42ba75fe3f
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html
@@ -0,0 +1,53 @@
+
+playbackRate
+
+
+
+