Skip to main content

script/dom/audio/
mediaelementaudiosourcenode.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::sync::mpsc;
6
7use dom_struct::dom_struct;
8use js::context::JSContext;
9use js::rust::HandleObject;
10use script_bindings::reflector::reflect_dom_object_with_proto_and_cx;
11use servo_media::audio::media_element_source_node::MediaElementSourceNodeMessage;
12use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage};
13
14use crate::dom::audio::audiocontext::AudioContext;
15use crate::dom::audio::audionode::AudioNode;
16use crate::dom::bindings::codegen::Bindings::MediaElementAudioSourceNodeBinding::{
17    MediaElementAudioSourceNodeMethods, MediaElementAudioSourceOptions,
18};
19use crate::dom::bindings::error::Fallible;
20use crate::dom::bindings::root::{Dom, DomRoot};
21use crate::dom::html::htmlmediaelement::HTMLMediaElement;
22use crate::dom::window::Window;
23
24#[dom_struct]
25pub(crate) struct MediaElementAudioSourceNode {
26    node: AudioNode,
27    media_element: Dom<HTMLMediaElement>,
28}
29
30impl MediaElementAudioSourceNode {
31    #[cfg_attr(crown, expect(crown::unrooted_must_root))]
32    fn new_inherited(
33        cx: &mut JSContext,
34        context: &AudioContext,
35        media_element: &HTMLMediaElement,
36    ) -> Fallible<MediaElementAudioSourceNode> {
37        let node = AudioNode::new_inherited(
38            cx,
39            AudioNodeInit::MediaElementSourceNode,
40            &context.base(),
41            Default::default(),
42            0,
43            1,
44        )?;
45        let (sender, receiver) = mpsc::channel();
46        node.message(AudioNodeMessage::MediaElementSourceNode(
47            MediaElementSourceNodeMessage::GetAudioRenderer(sender),
48        ));
49        let audio_renderer = receiver.recv();
50        media_element.set_audio_renderer(audio_renderer.ok(), cx);
51        let media_element = Dom::from_ref(media_element);
52        Ok(MediaElementAudioSourceNode {
53            node,
54            media_element,
55        })
56    }
57
58    pub(crate) fn new(
59        cx: &mut JSContext,
60        window: &Window,
61        context: &AudioContext,
62        media_element: &HTMLMediaElement,
63    ) -> Fallible<DomRoot<MediaElementAudioSourceNode>> {
64        Self::new_with_proto(cx, window, None, context, media_element)
65    }
66
67    #[cfg_attr(crown, expect(crown::unrooted_must_root))]
68    fn new_with_proto(
69        cx: &mut JSContext,
70        window: &Window,
71        proto: Option<HandleObject>,
72        context: &AudioContext,
73        media_element: &HTMLMediaElement,
74    ) -> Fallible<DomRoot<MediaElementAudioSourceNode>> {
75        let node = MediaElementAudioSourceNode::new_inherited(cx, context, media_element)?;
76        Ok(reflect_dom_object_with_proto_and_cx(
77            Box::new(node),
78            window,
79            proto,
80            cx,
81        ))
82    }
83}
84
85impl MediaElementAudioSourceNodeMethods<crate::DomTypeHolder> for MediaElementAudioSourceNode {
86    /// <https://webaudio.github.io/web-audio-api/#dom-mediaelementaudiosourcenode-mediaelementaudiosourcenode>
87    fn Constructor(
88        cx: &mut JSContext,
89        window: &Window,
90        proto: Option<HandleObject>,
91        context: &AudioContext,
92        options: &MediaElementAudioSourceOptions,
93    ) -> Fallible<DomRoot<MediaElementAudioSourceNode>> {
94        MediaElementAudioSourceNode::new_with_proto(
95            cx,
96            window,
97            proto,
98            context,
99            &options.mediaElement,
100        )
101    }
102
103    /// <https://webaudio.github.io/web-audio-api/#dom-mediaelementaudiosourcenode-mediaelement>
104    fn MediaElement(&self) -> DomRoot<HTMLMediaElement> {
105        DomRoot::from_ref(&*self.media_element)
106    }
107}