livekit_datatrack/
frame.rs1use bytes::Bytes;
16use core::fmt;
17use std::time::{Duration, SystemTime, UNIX_EPOCH};
18
19#[derive(Clone, Default)]
34pub struct DataTrackFrame {
35 pub(crate) payload: Bytes,
36 pub(crate) user_timestamp: Option<u64>,
37}
38
39impl DataTrackFrame {
40 pub fn payload(&self) -> Bytes {
42 self.payload.clone() }
44
45 pub fn user_timestamp(&self) -> Option<u64> {
47 self.user_timestamp
48 }
49
50 pub fn duration_since_timestamp(&self) -> Option<Duration> {
58 let ts = self.user_timestamp?;
59 let ts_time = UNIX_EPOCH.checked_add(Duration::from_millis(ts))?;
60 SystemTime::now()
61 .duration_since(ts_time)
62 .inspect_err(|err| log::error!("Failed to calculate duration: {err}"))
63 .ok()
64 }
65}
66
67impl DataTrackFrame {
68 pub fn new(payload: impl Into<Bytes>) -> Self {
70 Self { payload: payload.into(), ..Default::default() }
71 }
72
73 pub fn with_user_timestamp(mut self, value: u64) -> Self {
75 self.user_timestamp = Some(value);
76 self
77 }
78
79 pub fn with_user_timestamp_now(mut self) -> Self {
81 let timestamp = SystemTime::now()
82 .duration_since(std::time::UNIX_EPOCH)
83 .map(|d| d.as_millis() as u64)
84 .inspect_err(|err| log::error!("Failed to get system time: {err}"))
85 .ok();
86 self.user_timestamp = timestamp;
87 self
88 }
89}
90
91impl fmt::Debug for DataTrackFrame {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 f.debug_struct("DataTrackFrame")
94 .field("payload_len", &self.payload.len())
95 .field("user_timestamp", &self.user_timestamp)
96 .finish()
97 }
98}
99
100impl From<Bytes> for DataTrackFrame {
103 fn from(bytes: Bytes) -> Self {
104 Self { payload: bytes, ..Default::default() }
105 }
106}
107
108impl From<&'static [u8]> for DataTrackFrame {
109 fn from(slice: &'static [u8]) -> Self {
110 Self { payload: slice.into(), ..Default::default() }
111 }
112}
113
114impl From<Vec<u8>> for DataTrackFrame {
115 fn from(vec: Vec<u8>) -> Self {
116 Self { payload: vec.into(), ..Default::default() }
117 }
118}
119
120impl From<Box<[u8]>> for DataTrackFrame {
121 fn from(slice: Box<[u8]>) -> Self {
122 Self { payload: slice.into(), ..Default::default() }
123 }
124}