medea_jason/platform/dart/media_track.rs
1//! Representation of a [MediaStreamTrack][0].
2//!
3//! [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
4
5use dart_sys::Dart_Handle;
6use medea_macro::dart_bridge;
7
8use crate::{
9 media::{
10 FacingMode, MediaKind, MediaSourceKind, NoiseSuppressionLevel,
11 track::MediaStreamTrackState,
12 },
13 platform::{
14 self,
15 dart::utils::{
16 NonNullDartValueArgExt as _, callback::Callback,
17 dart_string_into_rust, handle::DartHandle,
18 },
19 utils::dart_future::FutureFromDart,
20 },
21};
22
23#[dart_bridge("flutter/lib/src/native/platform/media_track.g.dart")]
24mod media_stream_track {
25 use std::{os::raw::c_char, ptr};
26
27 use dart_sys::Dart_Handle;
28
29 use crate::{api::DartValueArg, platform::Error};
30
31 extern "C" {
32 /// Returns [ID][1] of the provided [MediaStreamTrack][0].
33 ///
34 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
35 /// [1]: https://w3.org/TR/mediacapture-streams#dom-mediastreamtrack-id
36 pub fn id(track: Dart_Handle) -> Result<ptr::NonNull<c_char>, Error>;
37
38 /// Returns [device ID][1] of the provided [MediaStreamTrack][0].
39 ///
40 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
41 /// [1]: https://w3.org/TR/mediacapture-streams#dfn-deviceid
42 pub fn device_id(
43 track: Dart_Handle,
44 ) -> Result<ptr::NonNull<c_char>, Error>;
45
46 /// Returns [kind][1] of the provided [MediaStreamTrack][0].
47 ///
48 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
49 /// [1]: https://tinyurl.com/w3-streams#dom-mediastreamtrack-kind
50 pub fn kind(track: Dart_Handle) -> Result<i64, Error>;
51
52 /// Returns [facing mode][1] of the provided [MediaStreamTrack][0].
53 ///
54 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
55 /// [1]: https://tinyurl.com/w3-streams#def-constraint-facingMode
56 pub fn facing_mode(
57 track: Dart_Handle,
58 ) -> Result<ptr::NonNull<DartValueArg<Option<i64>>>, Error>;
59
60 /// Returns [height][1] of the provided [MediaStreamTrack][0].
61 ///
62 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
63 /// [1]: https://tinyurl.com/w3-streams#dom-mediatracksettings-height
64 pub fn height(
65 track: Dart_Handle,
66 ) -> Result<ptr::NonNull<DartValueArg<Option<u32>>>, Error>;
67
68 /// Returns [width][1] of the provided [MediaStreamTrack][0].
69 ///
70 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
71 /// [1]: https://tinyurl.com/w3-streams#dom-mediatracksettings-width
72 pub fn width(
73 track: Dart_Handle,
74 ) -> Result<ptr::NonNull<DartValueArg<Option<u32>>>, Error>;
75
76 /// Returns [enabled][1] field of the provided [MediaStreamTrack][0].
77 ///
78 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
79 /// [1]: https://tinyurl.com/w3-streams#dom-mediastreamtrack-enabled
80 pub fn enabled(track: Dart_Handle) -> Result<bool, Error>;
81
82 /// Sets [enabled][1] field of the provided [MediaStreamTrack][0].
83 ///
84 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
85 /// [1]: https://tinyurl.com/w3-streams#dom-mediastreamtrack-enabled
86 pub fn set_enabled(
87 track: Dart_Handle,
88 is_enabled: bool,
89 ) -> Result<(), Error>;
90
91 /// Returns [readiness state][1] of the provided [MediaStreamTrack][0].
92 ///
93 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
94 /// [1]: https://tinyurl.com/w3-streams#dom-mediastreamtrack-readystate
95 pub fn ready_state(track: Dart_Handle) -> Result<Dart_Handle, Error>;
96
97 /// [Stops][1] the provided [MediaStreamTrack][0].
98 ///
99 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
100 /// [1]: https://tinyurl.com/w3-streams#dom-mediastreamtrack-stop
101 pub fn stop(track: Dart_Handle) -> Result<Dart_Handle, Error>;
102
103 /// Sets [`onended`][1] event handler of the provided
104 /// [MediaStreamTrack][0].
105 ///
106 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
107 /// [1]: https://tinyurl.com/w3-streams#dom-mediastreamtrack-onended
108 pub fn on_ended(
109 track: Dart_Handle,
110 cb: Dart_Handle,
111 ) -> Result<(), Error>;
112
113 /// Creates a new instance of [MediaStreamTrack][0] depending on the
114 /// same media source as the provided one has.
115 ///
116 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
117 pub fn clone(track: Dart_Handle) -> Result<Dart_Handle, Error>;
118
119 /// Disposes the provided [MediaStreamTrack][0].
120 ///
121 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
122 pub fn dispose(track: Dart_Handle) -> Result<Dart_Handle, Error>;
123
124 /// Indicates whether an `OnAudioLevelChangedCallback` is supported for
125 /// this [MediaStreamTrack][0].
126 ///
127 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
128 pub fn is_on_audio_level_available(
129 track: Dart_Handle,
130 ) -> Result<bool, Error>;
131
132 /// Sets the provided `OnAudioLevelChangedCallback` for the provided
133 /// [MediaStreamTrack][0].
134 ///
135 /// It's called for live [MediaStreamTrack][0]s when their audio level
136 /// changes.
137 ///
138 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
139 pub fn on_audio_level_changed(
140 track: Dart_Handle,
141 cb: Dart_Handle,
142 ) -> Result<(), Error>;
143
144 /// Indicates whether the provided [MediaStreamTrack][0] supports audio
145 /// processing functions.
146 ///
147 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
148 pub fn is_audio_processing_available(
149 track: Dart_Handle,
150 ) -> Result<bool, Error>;
151
152 /// Toggles noise suppression for the provided [MediaStreamTrack][0].
153 ///
154 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
155 pub fn set_noise_suppression_enabled(
156 track: Dart_Handle,
157 enable: bool,
158 ) -> Result<Dart_Handle, Error>;
159
160 /// Configures a noise suppression level for the provided
161 /// [MediaStreamTrack][0].
162 ///
163 /// __NOTE__: Only supported on desktop platforms.
164 ///
165 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
166 pub fn set_noise_suppression_level(
167 track: Dart_Handle,
168 level: i64,
169 ) -> Result<Dart_Handle, Error>;
170
171 /// Toggles echo cancellation for the provided [MediaStreamTrack][0].
172 ///
173 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
174 pub fn set_echo_cancellation_enabled(
175 track: Dart_Handle,
176 enable: bool,
177 ) -> Result<Dart_Handle, Error>;
178
179 /// Toggles auto gain control for the provided [MediaStreamTrack][0].
180 ///
181 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
182 pub fn set_auto_gain_control_enabled(
183 track: Dart_Handle,
184 enable: bool,
185 ) -> Result<Dart_Handle, Error>;
186
187 /// Toggles high-pass filter for the provided [MediaStreamTrack][0].
188 ///
189 /// __NOTE__: Only supported on desktop platforms.
190 ///
191 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
192 pub fn set_high_pass_filter_enabled(
193 track: Dart_Handle,
194 enable: bool,
195 ) -> Result<Dart_Handle, Error>;
196
197 /// Indicates whether noise suppression is enabled for the provided
198 /// [MediaStreamTrack][0].
199 ///
200 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
201 pub fn is_noise_suppression_enabled(
202 track: Dart_Handle,
203 ) -> Result<Dart_Handle, Error>;
204
205 /// Returns the current configured noise suppression level of the
206 /// provided [MediaStreamTrack][0].
207 ///
208 /// __NOTE__: Only supported on desktop platforms.
209 ///
210 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
211 pub fn get_noise_suppression_level(
212 track: Dart_Handle,
213 ) -> Result<Dart_Handle, Error>;
214
215 /// Indicates whether auto gain control is enabled for the provided
216 /// [MediaStreamTrack][0].
217 ///
218 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
219 pub fn is_auto_gain_control_enabled(
220 track: Dart_Handle,
221 ) -> Result<Dart_Handle, Error>;
222
223 /// Indicates whether echo cancellation is enabled for the provided
224 /// [MediaStreamTrack][0].
225 ///
226 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
227 pub fn is_echo_cancellation_enabled(
228 track: Dart_Handle,
229 ) -> Result<Dart_Handle, Error>;
230
231 /// Indicates whether high-pass filter is enabled for the provided
232 /// [MediaStreamTrack][0].
233 ///
234 /// __NOTE__: Only supported on desktop platforms.
235 ///
236 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
237 pub fn is_high_pass_filter_enabled(
238 track: Dart_Handle,
239 ) -> Result<Dart_Handle, Error>;
240 }
241}
242
243/// Representation of a [MediaStreamTrack][0] received from a
244/// [getUserMedia()][1] or a [getDisplayMedia()][2] request.
245///
246/// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
247/// [1]: https://w3.org/TR/mediacapture-streams#dom-mediadevices-getusermedia
248/// [2]: https://w3.org/TR/screen-capture#dom-mediadevices-getdisplaymedia
249#[derive(Clone, Debug)]
250pub struct MediaStreamTrack {
251 /// Pointer on the [MediaStreamTrack][0]
252 ///
253 /// [0]: https://w3.org/TR/mediacapture-streams#mediastreamtrack
254 inner: DartHandle,
255
256 /// Media source type of this [`MediaStreamTrack`].
257 source_kind: Option<MediaSourceKind>,
258}
259
260impl MediaStreamTrack {
261 /// Creates a new [`MediaStreamTrack`].
262 #[must_use]
263 pub const fn new(
264 inner: DartHandle,
265 source_kind: Option<MediaSourceKind>,
266 ) -> Self {
267 Self { inner, source_kind }
268 }
269
270 /// Returns the underlying [`Dart_Handle`] of this [`MediaStreamTrack`].
271 #[must_use]
272 pub fn handle(&self) -> Dart_Handle {
273 self.inner.get()
274 }
275
276 /// Returns [ID][1] of this [`MediaStreamTrack`].
277 ///
278 /// [1]: https://w3.org/TR/mediacapture-streams#dom-mediastreamtrack-id
279 #[must_use]
280 pub fn id(&self) -> String {
281 let id = unsafe { media_stream_track::id(self.inner.get()) }.unwrap();
282 unsafe { dart_string_into_rust(id) }
283 }
284
285 /// Returns [device ID][1] of this [`MediaStreamTrack`].
286 ///
287 /// [1]: https://w3.org/TR/mediacapture-streams#dfn-deviceid
288 #[expect(clippy::unwrap_in_result, reason = "unrelated")]
289 #[inline]
290 #[must_use]
291 pub fn device_id(&self) -> Option<String> {
292 let device_id =
293 unsafe { media_stream_track::device_id(self.inner.get()) }.unwrap();
294 Some(unsafe { dart_string_into_rust(device_id) })
295 }
296
297 /// Returns [kind][1] of this [`MediaStreamTrack`].
298 ///
299 /// [1]: https://w3.org/TR/mediacapture-streams#dom-mediastreamtrack-kind
300 #[inline]
301 #[must_use]
302 pub fn kind(&self) -> MediaKind {
303 MediaKind::try_from(
304 unsafe { media_stream_track::kind(self.inner.get()) }.unwrap(),
305 )
306 .unwrap()
307 }
308
309 /// Returns [facing mode][1] of this [`MediaStreamTrack`].
310 ///
311 /// [1]: https://tinyurl.com/w3-streams#dom-mediatracksettings-facingmode
312 #[expect(clippy::unwrap_in_result, reason = "unrelated")]
313 #[must_use]
314 pub fn facing_mode(&self) -> Option<FacingMode> {
315 let facing_mode =
316 unsafe { media_stream_track::facing_mode(self.inner.get()) }
317 .unwrap();
318 Option::<i64>::try_from(unsafe { facing_mode.unbox() })
319 .unwrap()
320 .map(FacingMode::try_from)
321 .transpose()
322 .unwrap()
323 }
324
325 /// Returns [height][1] of this [`MediaStreamTrack`].
326 ///
327 /// [1]: https://tinyurl.com/w3-streams#dom-mediatracksettings-height
328 #[expect(clippy::unwrap_in_result, reason = "unrelated")]
329 #[must_use]
330 pub fn height(&self) -> Option<u32> {
331 let height =
332 unsafe { media_stream_track::height(self.inner.get()) }.unwrap();
333 Option::try_from(unsafe { height.unbox() }).unwrap()
334 }
335
336 /// Returns [width][1] of this [`MediaStreamTrack`].
337 ///
338 /// [1]: https://tinyurl.com/w3-streams#dom-mediatracksettings-width
339 #[expect(clippy::unwrap_in_result, reason = "unrelated")]
340 #[must_use]
341 pub fn width(&self) -> Option<u32> {
342 let width =
343 unsafe { media_stream_track::width(self.inner.get()) }.unwrap();
344 Option::try_from(unsafe { width.unbox() }).unwrap()
345 }
346
347 /// Returns [enabled][1] field of this [`MediaStreamTrack`].
348 ///
349 /// [1]: https://w3.org/TR/mediacapture-streams#dom-mediastreamtrack-enabled
350 #[inline]
351 #[must_use]
352 pub fn enabled(&self) -> bool {
353 unsafe { media_stream_track::enabled(self.inner.get()) }.unwrap()
354 }
355
356 /// Sets [enabled][1] field of this [`MediaStreamTrack`].
357 ///
358 /// [1]: https://w3.org/TR/mediacapture-streams#dom-mediastreamtrack-enabled
359 pub fn set_enabled(&self, enabled: bool) {
360 unsafe { media_stream_track::set_enabled(self.inner.get(), enabled) }
361 .unwrap();
362 }
363
364 /// Returns [readiness state][1] of this [`MediaStreamTrack`].
365 ///
366 /// [1]: https://tinyurl.com/w3-streams#dom-mediastreamtrack-readystate
367 pub async fn ready_state(&self) -> MediaStreamTrackState {
368 let handle = self.inner.get();
369 let state = unsafe { media_stream_track::ready_state(handle) }.unwrap();
370 let state =
371 unsafe { FutureFromDart::execute::<i64>(state) }.await.unwrap();
372
373 match state {
374 0 => MediaStreamTrackState::Live,
375 1 => MediaStreamTrackState::Ended,
376 _ => unreachable!("Unknown `MediaStreamTrackState`: {state}"),
377 }
378 }
379
380 /// [Stops][1] this [`MediaStreamTrack`].
381 ///
382 /// [1]: https://w3.org/TR/mediacapture-streams#dom-mediastreamtrack-stop
383 #[inline]
384 pub fn stop(&self) -> impl Future<Output = ()> + 'static + use<> {
385 let inner = self.inner.clone();
386 async move {
387 let fut = unsafe { media_stream_track::stop(inner.get()) }.unwrap();
388 unsafe { FutureFromDart::execute::<()>(fut) }.await.unwrap();
389 }
390 }
391
392 /// Detects whether this video [`MediaStreamTrack`] is captured from
393 /// display, searching for [specific fields][1] in its settings.
394 ///
395 /// Only works in Chrome browser at the moment.
396 ///
397 /// [1]: https://w3.org/TR/screen-capture#extensions-to-mediatracksettings
398 #[must_use]
399 pub fn guess_is_from_display(&self) -> bool {
400 self.source_kind == Some(MediaSourceKind::Display)
401 }
402
403 /// Forks this [`MediaStreamTrack`], by creating a new [`MediaStreamTrack`]
404 /// from this [`MediaStreamTrack`] using a [`clone()`][1] method.
405 ///
406 /// __NOTE__: It won't clone [`MediaStreamTrack`]'s event handlers.
407 ///
408 /// # Naming
409 ///
410 /// The name of this method intentionally diverges from [the spec one][1] to
411 /// not interfere with [`Clone`] trait.
412 ///
413 /// [1]: https://w3.org/TR/mediacapture-streams#dom-mediastreamtrack-clone
414 pub async fn fork(&self) -> Self {
415 let fut =
416 unsafe { media_stream_track::clone(self.inner.get()) }.unwrap();
417 let new_track: DartHandle =
418 unsafe { FutureFromDart::execute(fut) }.await.unwrap();
419 Self::new(new_track, self.source_kind)
420 }
421
422 /// Sets [`onended`][1] event handler of this [`MediaStreamTrack`].
423 ///
424 /// [1]: https://tinyurl.com/w3-streams#dom-mediastreamtrack-onended
425 pub fn on_ended<F>(&self, f: Option<F>)
426 where
427 F: 'static + FnOnce(),
428 {
429 if let Some(cb) = f {
430 let cb = Callback::from_once(|(): ()| cb());
431 unsafe {
432 media_stream_track::on_ended(self.inner.get(), cb.into_dart())
433 }
434 .unwrap();
435 }
436 }
437
438 /// Indicates whether an `OnAudioLevelChangedCallback` is supported for this
439 /// [`MediaStreamTrack`].
440 #[must_use]
441 pub fn is_on_audio_level_available(&self) -> bool {
442 unsafe {
443 media_stream_track::is_on_audio_level_available(self.inner.get())
444 }
445 .unwrap()
446 }
447
448 /// Sets the provided `OnAudioLevelChangedCallback` for this
449 /// [`MediaStreamTrack`].
450 ///
451 /// It's called for live [`MediaStreamTrack`]s when their audio level
452 /// changes.
453 ///
454 /// # Errors
455 ///
456 /// Never errors.
457 #[expect(clippy::unwrap_in_result, reason = "unrelated and intended")]
458 pub fn on_audio_level_changed<F>(
459 &self,
460 mut f: F,
461 ) -> Result<(), platform::Error>
462 where
463 F: 'static + FnMut(i32),
464 {
465 let cb = Callback::from_fn_mut(move |value: i32| f(value));
466
467 unsafe {
468 media_stream_track::on_audio_level_changed(
469 self.inner.get(),
470 cb.into_dart(),
471 )
472 }
473 .unwrap();
474
475 Ok(())
476 }
477
478 /// Indicates whether this [`MediaStreamTrack`] supports audio processing
479 /// functions:
480 /// - [`MediaStreamTrack::is_noise_suppression_enabled()`]
481 /// - [`MediaStreamTrack::set_noise_suppression_enabled()`]
482 /// - [`MediaStreamTrack::get_noise_suppression_level()`]
483 /// - [`MediaStreamTrack::set_noise_suppression_level()`]
484 /// - [`MediaStreamTrack::is_echo_cancellation_enabled()`]
485 /// - [`MediaStreamTrack::set_echo_cancellation_enabled()`]
486 /// - [`MediaStreamTrack::is_auto_gain_control_enabled()`]
487 /// - [`MediaStreamTrack::set_auto_gain_control_enabled()`]
488 /// - [`MediaStreamTrack::is_high_pass_filter_enabled()`]
489 /// - [`MediaStreamTrack::set_high_pass_filter_enabled()`]
490 #[must_use]
491 pub fn is_audio_processing_available(&self) -> bool {
492 unsafe {
493 media_stream_track::is_audio_processing_available(self.inner.get())
494 }
495 .unwrap()
496 }
497
498 /// Toggles noise suppression for this [`MediaStreamTrack`].
499 ///
500 /// # Errors
501 ///
502 /// With a [`platform::Error`] if platform call errors.
503 pub async fn set_noise_suppression_enabled(
504 &self,
505 enabled: bool,
506 ) -> Result<(), platform::Error> {
507 let fut = unsafe {
508 media_stream_track::set_noise_suppression_enabled(
509 self.inner.get(),
510 enabled,
511 )
512 }?;
513 unsafe { FutureFromDart::execute::<()>(fut) }.await
514 }
515
516 /// Configures a [`NoiseSuppressionLevel`] for this [`MediaStreamTrack`].
517 ///
518 /// __NOTE__: Only supported on desktop platforms.
519 ///
520 /// # Errors
521 ///
522 /// With a [`platform::Error`] if platform call errors.
523 pub async fn set_noise_suppression_level(
524 &self,
525 level: NoiseSuppressionLevel,
526 ) -> Result<(), platform::Error> {
527 let fut = unsafe {
528 media_stream_track::set_noise_suppression_level(
529 self.inner.get(),
530 level as i64,
531 )
532 }?;
533 unsafe { FutureFromDart::execute::<()>(fut) }.await
534 }
535
536 /// Toggles acoustic echo cancellation for this [`MediaStreamTrack`].
537 ///
538 /// # Errors
539 ///
540 /// With a [`platform::Error`] if platform call errors.
541 pub async fn set_echo_cancellation_enabled(
542 &self,
543 enabled: bool,
544 ) -> Result<(), platform::Error> {
545 let fut = unsafe {
546 media_stream_track::set_echo_cancellation_enabled(
547 self.inner.get(),
548 enabled,
549 )
550 }?;
551 unsafe { FutureFromDart::execute::<()>(fut) }.await
552 }
553
554 /// Toggles auto gain control for this [`MediaStreamTrack`].
555 ///
556 /// # Errors
557 ///
558 /// With a [`platform::Error`] if platform call errors.
559 pub async fn set_auto_gain_control_enabled(
560 &self,
561 enabled: bool,
562 ) -> Result<(), platform::Error> {
563 let fut = unsafe {
564 media_stream_track::set_auto_gain_control_enabled(
565 self.inner.get(),
566 enabled,
567 )
568 }?;
569 unsafe { FutureFromDart::execute::<()>(fut) }.await
570 }
571
572 /// Toggles high-pass filter for this [`MediaStreamTrack`].
573 ///
574 /// __NOTE__: Only supported on desktop platforms.
575 ///
576 /// # Errors
577 ///
578 /// With a [`platform::Error`] if platform call errors.
579 pub async fn set_high_pass_filter_enabled(
580 &self,
581 enabled: bool,
582 ) -> Result<(), platform::Error> {
583 let fut = unsafe {
584 media_stream_track::set_high_pass_filter_enabled(
585 self.inner.get(),
586 enabled,
587 )
588 }?;
589 unsafe { FutureFromDart::execute::<()>(fut) }.await
590 }
591
592 /// Indicates whether noise suppression is enabled for this
593 /// [`MediaStreamTrack`].
594 ///
595 /// # Errors
596 ///
597 /// With a [`platform::Error`] if platform call errors.
598 pub async fn is_noise_suppression_enabled(
599 &self,
600 ) -> Result<bool, platform::Error> {
601 let fut = unsafe {
602 media_stream_track::is_noise_suppression_enabled(self.inner.get())
603 }?;
604 unsafe { FutureFromDart::execute::<bool>(fut) }.await
605 }
606
607 /// Returns the current configured [`NoiseSuppressionLevel`] of this
608 /// [`MediaStreamTrack`].
609 ///
610 /// __NOTE__: Only supported on desktop platforms.
611 ///
612 /// # Errors
613 ///
614 /// With a [`platform::Error`] if platform call errors.
615 pub async fn get_noise_suppression_level(
616 &self,
617 ) -> Result<NoiseSuppressionLevel, platform::Error> {
618 let fut = unsafe {
619 media_stream_track::get_noise_suppression_level(self.inner.get())
620 }?;
621 let level = unsafe { FutureFromDart::execute::<i64>(fut) }.await?;
622
623 Ok(NoiseSuppressionLevel::try_from(level).unwrap())
624 }
625
626 /// Indicates whether auto gain control is enabled for this
627 /// [`MediaStreamTrack`].
628 ///
629 /// # Errors
630 ///
631 /// With a [`platform::Error`] if platform call errors.
632 pub async fn is_auto_gain_control_enabled(
633 &self,
634 ) -> Result<bool, platform::Error> {
635 let fut = unsafe {
636 media_stream_track::is_auto_gain_control_enabled(self.inner.get())
637 }?;
638 unsafe { FutureFromDart::execute::<bool>(fut) }.await
639 }
640
641 /// Indicates whether echo cancellation is enabled for this
642 /// [`MediaStreamTrack`].
643 ///
644 /// # Errors
645 ///
646 /// With a [`platform::Error`] if platform call errors.
647 pub async fn is_echo_cancellation_enabled(
648 &self,
649 ) -> Result<bool, platform::Error> {
650 let fut = unsafe {
651 media_stream_track::is_echo_cancellation_enabled(self.inner.get())
652 }?;
653 unsafe { FutureFromDart::execute::<bool>(fut) }.await
654 }
655
656 /// Indicates whether high-pass filter is enabled for this
657 /// [`MediaStreamTrack`].
658 ///
659 /// __NOTE__: Only supported on desktop platforms.
660 ///
661 /// # Errors
662 ///
663 /// With a [`platform::Error`] if platform call errors.
664 pub async fn is_high_pass_filter_enabled(
665 &self,
666 ) -> Result<bool, platform::Error> {
667 let fut = unsafe {
668 media_stream_track::is_high_pass_filter_enabled(self.inner.get())
669 }?;
670 unsafe { FutureFromDart::execute::<bool>(fut) }.await
671 }
672}
673
674impl Drop for MediaStreamTrack {
675 fn drop(&mut self) {
676 let track = self.inner.clone();
677 platform::spawn(async move {
678 let fut =
679 unsafe { media_stream_track::dispose(track.get()) }.unwrap();
680 unsafe { FutureFromDart::execute::<()>(fut) }.await.unwrap();
681 });
682 }
683}