Skip to content

Commit 77ea7a6

Browse files
committed
feat: add timestamp to stream stats
This commit adds the timestamp since the stream started to the stream stats object.
1 parent 99b29df commit 77ea7a6

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

server/app.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def __init__(self, track: MediaStreamTrack, pipeline: Pipeline):
5959
self._lock = asyncio.Lock()
6060
self._fps_interval_frame_count = 0
6161
self._last_fps_calculation_time = time.monotonic()
62+
self._fps_loop_start_time = self._last_fps_calculation_time
6263
self._fps = 0.0
6364
self._fps_measurements = deque(maxlen=60)
6465
self._running_event = asyncio.Event()
@@ -76,25 +77,26 @@ async def collect_frames(self):
7677
except Exception as e:
7778
await self.pipeline.cleanup()
7879
raise Exception(f"Error collecting video frames: {str(e)}")
79-
80+
8081
async def _calculate_fps_loop(self):
8182
"""Loop to calculate FPS periodically."""
8283
await self._running_event.wait()
84+
self._fps_loop_start_time = time.monotonic()
8385
while self.readyState != "ended":
8486
await asyncio.sleep(1) # Calculate FPS every second.
8587
async with self._lock:
86-
current_time = time.monotonic()
87-
time_diff = current_time - self._last_fps_calculation_time
88+
current_time_monotonic = time.monotonic()
89+
time_diff = current_time_monotonic - self._last_fps_calculation_time
8890
if time_diff > 0:
8991
self._fps = self._fps_interval_frame_count / time_diff
9092
self._fps_measurements.append(
9193
self._fps
9294
) # Store the FPS measurement
9395

9496
# Reset start_time and frame_count for the next interval.
95-
self._last_fps_calculation_time = current_time
97+
self._last_fps_calculation_time = current_time_monotonic
9698
self._fps_interval_frame_count = 0
97-
99+
98100
@property
99101
async def fps(self) -> float:
100102
"""Get the current output frames per second (FPS).
@@ -127,17 +129,28 @@ async def average_fps(self) -> float:
127129
return 0.0
128130
return sum(self._fps_measurements) / len(self._fps_measurements)
129131

132+
@property
133+
async def last_fps_calculation_time(self) -> float:
134+
"""Get the elapsed time since the last FPS calculation.
135+
136+
Returns:
137+
The elapsed time in seconds since the last FPS calculation.
138+
"""
139+
async with self._lock:
140+
return self._last_fps_calculation_time - self._fps_loop_start_time
141+
130142
async def recv(self):
131143
processed_frame = await self.pipeline.get_processed_video_frame()
132-
144+
133145
# Increment frame count for FPS calculation.
134146
async with self._lock:
135147
self._fps_interval_frame_count += 1
136148
if not self._running_event.is_set():
137149
self._running_event.set()
138-
150+
139151
return processed_frame
140152

153+
141154
class AudioStreamTrack(MediaStreamTrack):
142155
kind = "audio"
143156
def __init__(self, track: MediaStreamTrack, pipeline):

server/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ async def collect_video_metrics(self, video_track: MediaStreamTrack) -> Dict[str
8888
A dictionary containing FPS-related statistics.
8989
"""
9090
return {
91+
"timestamp": await video_track.last_fps_calculation_time,
9192
"fps": await video_track.fps,
9293
"minute_avg_fps": await video_track.average_fps,
9394
"minute_fps_array": await video_track.fps_measurements,

0 commit comments

Comments
 (0)