Skip to content

Commit 223be69

Browse files
committed
put timestamp on frames
1 parent 1920690 commit 223be69

File tree

2 files changed

+36
-18
lines changed

2 files changed

+36
-18
lines changed

examples/video-stream/video_play.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@
1313

1414
try:
1515
import av
16-
import cv2
1716
except ImportError:
1817
raise RuntimeError(
19-
"av and opencv-python is required to run this example, install with `pip install av opencv-python`"
18+
"av is required to run this example, install with `pip install av`"
2019
)
2120

2221
# ensure LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET are set
@@ -52,32 +51,18 @@ def __init__(self, media_file: Union[str, Path]) -> None:
5251
audio_sample_rate=audio_stream.sample_rate,
5352
audio_channels=audio_stream.channels,
5453
)
55-
print(self._info)
5654

5755
@property
5856
def info(self) -> MediaInfo:
5957
return self._info
6058

61-
async def stream_video(
62-
self, av_sync: rtc.AVSynchronizer
63-
) -> AsyncIterable[tuple[rtc.VideoFrame, float]]:
59+
async def stream_video(self) -> AsyncIterable[tuple[rtc.VideoFrame, float]]:
6460
"""Streams video frames from the media file in an endless loop."""
6561
for i, av_frame in enumerate(self._video_container.decode(video=0)):
6662
# Convert video frame to RGBA
6763
frame = av_frame.to_rgb().to_ndarray()
6864
frame_rgba = np.ones((frame.shape[0], frame.shape[1], 4), dtype=np.uint8)
6965
frame_rgba[:, :, :3] = frame
70-
71-
# put fps and timestamps in the frame
72-
frame_rgba = cv2.putText(
73-
frame_rgba, f"{av_sync.actual_fps:.2f}fps", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2
74-
)
75-
76-
if i % 10 == 0:
77-
print(
78-
f"decoded frame {i} ({av_frame.time:.3f}s), {av_sync.actual_fps:.2f}fps, "
79-
f"last video time: {av_sync.last_video_time:.3f}s, last audio time: {av_sync.last_audio_time:.3f}s"
80-
)
8166
yield (
8267
rtc.VideoFrame(
8368
width=frame.shape[1],
@@ -190,7 +175,7 @@ async def _push_frames(
190175
while True:
191176
streamer.reset()
192177
video_task = asyncio.create_task(
193-
_push_frames(streamer.stream_video(av_sync), av_sync)
178+
_push_frames(streamer.stream_video(), av_sync)
194179
)
195180
audio_task = asyncio.create_task(
196181
_push_frames(streamer.stream_audio(), av_sync)

livekit-rtc/livekit/rtc/synchronizer.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from .audio_frame import AudioFrame
99
from .audio_source import AudioSource
1010
from .video_source import VideoSource
11+
import numpy as np
12+
import cv2
1113

1214
logger = logging.getLogger(__name__)
1315

@@ -84,8 +86,39 @@ async def wait_for_playout(self) -> None:
8486
await self._video_queue.join()
8587

8688
async def _capture_video(self) -> None:
89+
count = 0
8790
while not self._stopped:
8891
frame, timestamp = await self._video_queue.get()
92+
93+
# debug
94+
frame_rgba = np.frombuffer(frame.data, dtype=np.uint8).reshape(
95+
frame.height, frame.width, 4
96+
)
97+
frame_bgr = cv2.cvtColor(frame_rgba[:, :, :3], cv2.COLOR_RGBA2BGR)
98+
frame_bgr = cv2.putText(
99+
frame_bgr,
100+
f"{self.actual_fps:.2f}fps, video time: {timestamp:.3f}s, audio time: {self.last_audio_time:.3f}s",
101+
(10, 100),
102+
cv2.FONT_HERSHEY_SIMPLEX,
103+
1,
104+
(0, 0, 255),
105+
2,
106+
)
107+
frame_rgba = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGBA)
108+
frame = VideoFrame(
109+
width=frame.width,
110+
height=frame.height,
111+
type=frame.type,
112+
data=frame_rgba.tobytes(),
113+
)
114+
count += 1
115+
if count % 30 == 0:
116+
print(
117+
f"{self.actual_fps:.2f}fps, last video time: {self.last_video_time:.3f}s, "
118+
f"last audio time: {self.last_audio_time:.3f}s"
119+
)
120+
# end debug
121+
89122
async with self._fps_controller:
90123
self._video_source.capture_frame(frame)
91124
if timestamp is not None:

0 commit comments

Comments
 (0)