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