1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
use crate::errors::{Error, NativeError}; use js_sys::Object; use log::info; use std::cell::{Cell, RefCell}; use std::rc::Rc; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; use web_sys::{AudioBuffer, AudioBufferSourceNode, AudioContext, AudioNode, Element, Event}; pub struct AudioPlayer { pub node: AudioBufferSourceNode, pub cb: Option<Closure<dyn FnMut() -> ()>>, } impl AudioPlayer { pub fn start<F>( ctx: &AudioContext, buffer: &AudioBuffer, on_ended: Option<F>, ) -> Result<Self, Error> where F: FnMut() -> () + 'static, { let node = ctx.create_buffer_source()?; node.set_buffer(Some(buffer)); node.connect_with_audio_node(&ctx.destination())?; let cb: Option<Closure<dyn FnMut() -> ()>> = match on_ended { Some(f) => { let cb = Closure::wrap(Box::new(f) as Box<dyn FnMut() -> ()>); node.set_onended(Some(cb.as_ref().unchecked_ref())); Some(cb) } None => None, }; node.start()?; Ok(Self { node, cb }) } } impl Drop for AudioPlayer { fn drop(&mut self) { self.node.stop().unwrap(); self.node.set_onended(None); self.cb.take(); } }