gosuto_livekit/room/publication/
local.rs1use std::{fmt::Debug, sync::Arc};
16
17use livekit_protocol::{self as proto, AudioTrackFeature};
18use parking_lot::Mutex;
19
20use super::TrackPublicationInner;
21use crate::{e2ee::EncryptionType, options::TrackPublishOptions, prelude::*};
22
23#[derive(Default)]
24struct LocalInfo {
25 publish_options: Mutex<TrackPublishOptions>,
26}
27
28#[derive(Clone)]
29pub struct LocalTrackPublication {
30 inner: Arc<TrackPublicationInner>,
31 local: Arc<LocalInfo>,
32}
33
34impl Debug for LocalTrackPublication {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 f.debug_struct("LocalTrackPublication")
37 .field("sid", &self.sid())
38 .field("name", &self.name())
39 .field("kind", &self.kind())
40 .finish()
41 }
42}
43
44impl LocalTrackPublication {
45 pub(crate) fn new(info: proto::TrackInfo, track: LocalTrack) -> Self {
46 Self {
47 inner: super::new_inner(info, Some(track.into())),
48 local: Arc::new(LocalInfo::default()),
49 }
50 }
51
52 pub(crate) fn on_muted(&self, f: impl Fn(TrackPublication) + Send + 'static) {
53 *self.inner.events.muted.lock() = Some(Box::new(f));
54 }
55
56 pub(crate) fn on_unmuted(&self, f: impl Fn(TrackPublication) + Send + 'static) {
57 *self.inner.events.unmuted.lock() = Some(Box::new(f));
58 }
59
60 pub(crate) fn set_track(&self, track: Option<Track>) {
61 super::set_track(&self.inner, &TrackPublication::Local(self.clone()), track);
62 }
63
64 pub(crate) fn proto_info(&self) -> proto::TrackInfo {
65 self.inner.info.read().proto_info.clone()
66 }
67
68 #[allow(dead_code)]
69 pub(crate) fn update_info(&self, info: proto::TrackInfo) {
70 super::update_info(&self.inner, &TrackPublication::Local(self.clone()), info);
71 }
72
73 pub(crate) fn update_publish_options(&self, opts: TrackPublishOptions) {
74 *self.local.publish_options.lock() = opts;
75 }
76
77 pub fn publish_options(&self) -> TrackPublishOptions {
78 self.local.publish_options.lock().clone()
79 }
80
81 pub fn mute(&self) {
82 if let Some(track) = self.track() {
83 track.mute();
84 }
85
86 if let Some(mute_update_needed) = self.inner.events.muted.lock().as_ref() {
87 mute_update_needed(TrackPublication::Local(self.clone()))
88 }
89 }
90
91 pub fn unmute(&self) {
92 if let Some(track) = self.track() {
93 track.unmute();
94 }
95
96 if let Some(unmute_update_needed) = self.inner.events.unmuted.lock().as_ref() {
97 unmute_update_needed(TrackPublication::Local(self.clone()))
98 }
99 }
100
101 pub fn sid(&self) -> TrackSid {
102 self.inner.info.read().sid.clone()
103 }
104
105 pub fn name(&self) -> String {
106 self.inner.info.read().name.clone()
107 }
108
109 pub fn kind(&self) -> TrackKind {
110 self.inner.info.read().kind
111 }
112
113 pub fn source(&self) -> TrackSource {
114 self.inner.info.read().source
115 }
116
117 pub fn simulcasted(&self) -> bool {
118 self.inner.info.read().simulcasted
119 }
120
121 pub fn dimension(&self) -> TrackDimension {
122 self.inner.info.read().dimension
123 }
124
125 pub fn track(&self) -> Option<LocalTrack> {
126 self.inner.info.read().track.clone().map(|track| track.try_into().unwrap())
127 }
128
129 pub fn mime_type(&self) -> String {
130 self.inner.info.read().mime_type.clone()
131 }
132
133 pub fn is_muted(&self) -> bool {
134 if let Some(track) = self.track() {
135 return track.is_muted();
136 }
137
138 self.inner.info.read().muted
139 }
140
141 pub fn is_remote(&self) -> bool {
142 false
143 }
144
145 pub fn encryption_type(&self) -> EncryptionType {
146 self.inner.info.read().encryption_type
147 }
148
149 pub fn audio_features(&self) -> Vec<AudioTrackFeature> {
150 self.inner.info.read().audio_features.clone()
151 }
152}