gosuto_livekit/room/track/
remote_track.rs1use std::sync::Arc;
16
17use gosuto_libwebrtc::{prelude::*, stats::RtcStats};
18use livekit_protocol as proto;
19use livekit_protocol::enum_dispatch;
20
21use super::{track_dispatch, TrackInner};
22use crate::prelude::*;
23
24#[derive(Clone, Debug)]
25pub enum RemoteTrack {
26 Audio(RemoteAudioTrack),
27 Video(RemoteVideoTrack),
28}
29
30impl RemoteTrack {
31 track_dispatch!([Audio, Video]);
32
33 #[inline]
34 pub fn rtc_track(&self) -> MediaStreamTrack {
35 match self {
36 Self::Audio(track) => track.rtc_track().into(),
37 Self::Video(track) => track.rtc_track().into(),
38 }
39 }
40
41 pub async fn get_stats(&self) -> RoomResult<Vec<RtcStats>> {
42 match self {
43 Self::Audio(track) => track.get_stats().await,
44 Self::Video(track) => track.get_stats().await,
45 }
46 }
47}
48
49pub(super) async fn get_stats(inner: &Arc<TrackInner>) -> RoomResult<Vec<RtcStats>> {
50 let transceiver = inner.info.read().transceiver.clone();
51 let Some(transceiver) = transceiver.as_ref() else {
52 return Err(RoomError::Internal("no transceiver found for track".into()));
53 };
54
55 Ok(transceiver.receiver().get_stats().await?)
56}
57
58pub(super) fn update_info(inner: &Arc<TrackInner>, track: &Track, new_info: proto::TrackInfo) {
59 super::update_info(inner, track, new_info.clone());
60 super::set_muted(inner, track, new_info.muted);
61}
62
63impl From<RemoteTrack> for Track {
64 fn from(track: RemoteTrack) -> Self {
65 match track {
66 RemoteTrack::Audio(track) => Self::RemoteAudio(track),
67 RemoteTrack::Video(track) => Self::RemoteVideo(track),
68 }
69 }
70}
71
72impl TryFrom<Track> for RemoteTrack {
73 type Error = &'static str;
74
75 fn try_from(track: Track) -> Result<Self, Self::Error> {
76 match track {
77 Track::RemoteAudio(track) => Ok(Self::Audio(track)),
78 Track::RemoteVideo(track) => Ok(Self::Video(track)),
79 _ => Err("not a local track"),
80 }
81 }
82}