use std::rc::Rc;
use derive_more::with_trait::AsRef;
use medea_client_api_proto as proto;
use tracerr::Traced;
use crate::{
media::{
AudioLevelError, AudioProcessingError, MediaKind, MediaSourceKind,
MediaStreamTrackState, NoiseSuppressionLevel,
},
platform,
};
#[derive(AsRef, Debug)]
pub struct Track {
#[as_ref]
inner: platform::MediaStreamTrack,
source_kind: proto::MediaSourceKind,
_parent: Option<Rc<Self>>,
}
impl Track {
#[must_use]
pub const fn new(
track: platform::MediaStreamTrack,
source_kind: proto::MediaSourceKind,
) -> Self {
Self { inner: track, source_kind, _parent: None }
}
#[must_use]
pub const fn platform_track(&self) -> &platform::MediaStreamTrack {
&self.inner
}
pub fn set_enabled(&self, enabled: bool) {
self.inner.set_enabled(enabled);
}
#[must_use]
pub fn id(&self) -> String {
self.inner.id()
}
#[must_use]
pub const fn media_source_kind(&self) -> proto::MediaSourceKind {
self.source_kind
}
#[cfg_attr(
target_family = "wasm",
expect(clippy::missing_const_for_fn, reason = "not on all platforms")
)]
#[must_use]
pub fn kind(&self) -> MediaKind {
self.inner.kind()
}
pub fn on_ended(&self, callback: platform::Function<()>) {
self.inner.on_ended(Some(move || callback.call0()));
}
pub async fn state(&self) -> MediaStreamTrackState {
self.inner.ready_state().await
}
pub async fn fork(self: &Rc<Self>) -> Self {
let parent = Rc::clone(self);
let track = self.inner.fork().await;
Self {
inner: track,
source_kind: self.source_kind,
_parent: Some(parent),
}
}
pub async fn stop(&self) {
self.inner.stop().await;
}
}
impl Drop for Track {
fn drop(&mut self) {
platform::spawn(Box::pin(self.inner.stop()));
}
}
#[derive(Debug, Clone)]
pub struct LocalMediaTrackImpl(Rc<Track>);
impl LocalMediaTrackImpl {
#[must_use]
pub const fn new(track: Rc<Track>) -> Self {
Self(track)
}
#[must_use]
pub fn get_track(&self) -> &platform::MediaStreamTrack {
&self.0.inner
}
#[must_use]
pub fn kind(&self) -> MediaKind {
self.0.kind()
}
pub fn on_ended(&self, callback: platform::Function<()>) {
self.0.on_ended(callback);
}
pub async fn state(&self) -> MediaStreamTrackState {
self.0.state().await
}
#[must_use]
pub fn is_on_audio_level_available(&self) -> bool {
self.0.inner.is_on_audio_level_available()
}
pub fn on_audio_level_changed(
&self,
callback: platform::Function<i32>,
) -> Result<(), Traced<AudioLevelError>> {
self.0
.inner
.on_audio_level_changed(move |v| callback.call1(v))
.map_err(AudioLevelError::from)
.map_err(tracerr::wrap!())
}
#[must_use]
pub fn is_audio_processing_available(&self) -> bool {
self.0.inner.is_audio_processing_available()
}
pub async fn set_noise_suppression_enabled(
&self,
enabled: bool,
) -> Result<(), Traced<AudioProcessingError>> {
self.0
.inner
.set_noise_suppression_enabled(enabled)
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
pub async fn set_noise_suppression_level(
&self,
level: NoiseSuppressionLevel,
) -> Result<(), Traced<AudioProcessingError>> {
self.0
.inner
.set_noise_suppression_level(level)
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
pub async fn set_echo_cancellation_enabled(
&self,
enabled: bool,
) -> Result<(), Traced<AudioProcessingError>> {
self.0
.inner
.set_echo_cancellation_enabled(enabled)
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
pub async fn set_auto_gain_control_enabled(
&self,
enabled: bool,
) -> Result<(), Traced<AudioProcessingError>> {
self.0
.inner
.set_auto_gain_control_enabled(enabled)
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
pub async fn set_high_pass_filter_enabled(
&self,
enabled: bool,
) -> Result<(), Traced<AudioProcessingError>> {
self.0
.inner
.set_high_pass_filter_enabled(enabled)
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
pub async fn is_noise_suppression_enabled(
&self,
) -> Result<bool, Traced<AudioProcessingError>> {
self.0
.inner
.is_noise_suppression_enabled()
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
pub async fn get_noise_suppression_level(
&self,
) -> Result<NoiseSuppressionLevel, Traced<AudioProcessingError>> {
self.0
.inner
.get_noise_suppression_level()
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
pub async fn is_auto_gain_control_enabled(
&self,
) -> Result<bool, Traced<AudioProcessingError>> {
self.0
.inner
.is_auto_gain_control_enabled()
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
pub async fn is_echo_cancellation_enabled(
&self,
) -> Result<bool, Traced<AudioProcessingError>> {
self.0
.inner
.is_echo_cancellation_enabled()
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
pub async fn is_high_pass_filter_enabled(
&self,
) -> Result<bool, Traced<AudioProcessingError>> {
self.0
.inner
.is_high_pass_filter_enabled()
.await
.map_err(AudioProcessingError::from)
.map_err(tracerr::wrap!())
}
#[must_use]
pub fn media_source_kind(&self) -> MediaSourceKind {
self.0.media_source_kind().into()
}
pub async fn maybe_stop(mut self) {
if let Some(track) = Rc::get_mut(&mut self.0) {
track.stop().await;
}
}
}