Skip to main content

gosuto_livekit/room/track/
remote_video_track.rs

1// Copyright 2025 LiveKit, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::{fmt::Debug, sync::Arc};
16
17use gosuto_libwebrtc::{prelude::*, stats::RtcStats};
18use livekit_protocol as proto;
19
20use super::{remote_track, TrackInner};
21use crate::prelude::*;
22
23#[derive(Clone)]
24pub struct RemoteVideoTrack {
25    inner: Arc<TrackInner>,
26}
27
28impl Debug for RemoteVideoTrack {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        f.debug_struct("RemoteVideoTrack")
31            .field("sid", &self.sid())
32            .field("name", &self.name())
33            .field("source", &self.source())
34            .finish()
35    }
36}
37
38impl RemoteVideoTrack {
39    pub(crate) fn new(sid: TrackSid, name: String, rtc_track: RtcVideoTrack) -> Self {
40        Self {
41            inner: Arc::new(super::new_inner(
42                sid,
43                name,
44                TrackKind::Video,
45                MediaStreamTrack::Video(rtc_track),
46            )),
47        }
48    }
49
50    pub fn sid(&self) -> TrackSid {
51        self.inner.info.read().sid.clone()
52    }
53
54    pub fn name(&self) -> String {
55        self.inner.info.read().name.clone()
56    }
57
58    pub fn kind(&self) -> TrackKind {
59        self.inner.info.read().kind
60    }
61
62    pub fn source(&self) -> TrackSource {
63        self.inner.info.read().source
64    }
65
66    pub fn stream_state(&self) -> StreamState {
67        self.inner.info.read().stream_state
68    }
69
70    pub fn is_enabled(&self) -> bool {
71        self.inner.rtc_track.enabled()
72    }
73
74    pub fn enable(&self) {
75        self.inner.rtc_track.set_enabled(true);
76    }
77
78    pub fn disable(&self) {
79        self.inner.rtc_track.set_enabled(false);
80    }
81
82    pub fn is_muted(&self) -> bool {
83        self.inner.info.read().muted
84    }
85
86    pub fn rtc_track(&self) -> RtcVideoTrack {
87        if let MediaStreamTrack::Video(video) = self.inner.rtc_track.clone() {
88            return video;
89        }
90        unreachable!();
91    }
92
93    pub fn is_remote(&self) -> bool {
94        true
95    }
96
97    pub async fn get_stats(&self) -> RoomResult<Vec<RtcStats>> {
98        super::remote_track::get_stats(&self.inner).await
99    }
100
101    pub(crate) fn on_muted(&self, f: impl Fn(Track) + Send + 'static) {
102        self.inner.events.lock().muted.replace(Box::new(f));
103    }
104
105    pub(crate) fn on_unmuted(&self, f: impl Fn(Track) + Send + 'static) {
106        self.inner.events.lock().unmuted.replace(Box::new(f));
107    }
108
109    pub(crate) fn transceiver(&self) -> Option<RtpTransceiver> {
110        self.inner.info.read().transceiver.clone()
111    }
112
113    pub(crate) fn set_transceiver(&self, transceiver: Option<RtpTransceiver>) {
114        self.inner.info.write().transceiver = transceiver;
115    }
116
117    pub(crate) fn update_info(&self, info: proto::TrackInfo) {
118        remote_track::update_info(&self.inner, &Track::RemoteVideo(self.clone()), info);
119    }
120}