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