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