diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 7ec4cbffa86..dc96a8f325e 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -800,6 +800,7 @@ set(SOURCES WebAudio/DelayNode.cpp WebAudio/DynamicsCompressorNode.cpp WebAudio/GainNode.cpp + WebAudio/MediaElementAudioSourceNode.cpp WebAudio/OfflineAudioContext.cpp WebAudio/OscillatorNode.cpp WebAudio/PannerNode.cpp diff --git a/Libraries/LibWeb/WebAudio/MediaElementAudioSourceNode.cpp b/Libraries/LibWeb/WebAudio/MediaElementAudioSourceNode.cpp new file mode 100644 index 00000000000..8584722f3e6 --- /dev/null +++ b/Libraries/LibWeb/WebAudio/MediaElementAudioSourceNode.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025, Tim Ledbetter + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +namespace Web::WebAudio { + +GC_DEFINE_ALLOCATOR(MediaElementAudioSourceNode); + +MediaElementAudioSourceNode::MediaElementAudioSourceNode(JS::Realm& realm, GC::Ref context, MediaElementAudioSourceOptions const& options) + : AudioNode(realm, context) + , m_media_element(*options.media_element) +{ +} + +MediaElementAudioSourceNode::~MediaElementAudioSourceNode() = default; + +WebIDL::ExceptionOr> MediaElementAudioSourceNode::create(JS::Realm& realm, GC::Ref context, MediaElementAudioSourceOptions const& options) +{ + return construct_impl(realm, context, options); +} + +WebIDL::ExceptionOr> MediaElementAudioSourceNode::construct_impl(JS::Realm& realm, GC::Ref context, MediaElementAudioSourceOptions const& options) +{ + return realm.create(realm, context, options); +} + +void MediaElementAudioSourceNode::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + WEB_SET_PROTOTYPE_FOR_INTERFACE(MediaElementAudioSourceNode); +} + +void MediaElementAudioSourceNode::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_media_element); +} + +} diff --git a/Libraries/LibWeb/WebAudio/MediaElementAudioSourceNode.h b/Libraries/LibWeb/WebAudio/MediaElementAudioSourceNode.h new file mode 100644 index 00000000000..6c2b292142e --- /dev/null +++ b/Libraries/LibWeb/WebAudio/MediaElementAudioSourceNode.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025, Tim Ledbetter + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::WebAudio { + +// https://webaudio.github.io/web-audio-api/#MediaElementAudioSourceOptions +struct MediaElementAudioSourceOptions { + GC::Ptr media_element; +}; + +// https://webaudio.github.io/web-audio-api/#MediaElementAudioSourceNode +class MediaElementAudioSourceNode final : public AudioNode { + WEB_PLATFORM_OBJECT(MediaElementAudioSourceNode, AudioNode); + GC_DECLARE_ALLOCATOR(MediaElementAudioSourceNode); + +public: + virtual ~MediaElementAudioSourceNode() override; + + static WebIDL::ExceptionOr> create(JS::Realm&, GC::Ref, MediaElementAudioSourceOptions const&); + static WebIDL::ExceptionOr> construct_impl(JS::Realm&, GC::Ref, MediaElementAudioSourceOptions const&); + + virtual WebIDL::UnsignedLong number_of_inputs() override { return 0; } + virtual WebIDL::UnsignedLong number_of_outputs() override { return 1; } + + GC::Ref media_element() const { return m_media_element; } + +private: + MediaElementAudioSourceNode(JS::Realm&, GC::Ref, MediaElementAudioSourceOptions const&); + + virtual void initialize(JS::Realm&) override; + virtual void visit_edges(Cell::Visitor&) override; + + GC::Ref m_media_element; +}; + +} diff --git a/Libraries/LibWeb/WebAudio/MediaElementAudioSourceNode.idl b/Libraries/LibWeb/WebAudio/MediaElementAudioSourceNode.idl new file mode 100644 index 00000000000..c2e3252d6a2 --- /dev/null +++ b/Libraries/LibWeb/WebAudio/MediaElementAudioSourceNode.idl @@ -0,0 +1,17 @@ +#import +#import +#import +#import +#import + +// https://webaudio.github.io/web-audio-api/#MediaElementAudioSourceOptions +dictionary MediaElementAudioSourceOptions { + required HTMLMediaElement mediaElement; +}; + +// https://webaudio.github.io/web-audio-api/#MediaElementAudioSourceNode +[Exposed=Window] +interface MediaElementAudioSourceNode : AudioNode { + constructor (AudioContext context, MediaElementAudioSourceOptions options); + [SameObject] readonly attribute HTMLMediaElement mediaElement; +}; diff --git a/Libraries/LibWeb/idl_files.cmake b/Libraries/LibWeb/idl_files.cmake index f971ee2d7e3..3faa51f3f95 100644 --- a/Libraries/LibWeb/idl_files.cmake +++ b/Libraries/LibWeb/idl_files.cmake @@ -374,6 +374,7 @@ libweb_js_bindings(WebAudio/ChannelMergerNode) libweb_js_bindings(WebAudio/ChannelSplitterNode) libweb_js_bindings(WebAudio/ConstantSourceNode) libweb_js_bindings(WebAudio/DelayNode) +libweb_js_bindings(WebAudio/MediaElementAudioSourceNode) libweb_js_bindings(WebAudio/OfflineAudioContext) libweb_js_bindings(WebAudio/OscillatorNode) libweb_js_bindings(WebAudio/PannerNode) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index d36203836cb..3f04e2e6759 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -35,6 +35,7 @@ static bool is_platform_object(Type const& type) "AnimationTimeline"sv, "Attr"sv, "AudioBuffer"sv, + "AudioContext"sv, "AudioListener"sv, "AudioNode"sv, "AudioParam"sv, diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index 795e56130f3..e24b4682d2d 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -234,6 +234,7 @@ ManagedSourceBuffer Map MathMLElement MediaCapabilities +MediaElementAudioSourceNode MediaError MediaList MediaQueryList