I am working with an RTSP stream from a Hikvision camera, which has its internal time synchronized via NTP. I am trying to extract timestamps from the video frames using OpenCV and GStreamer. My goal is to retrieve the NTP timestamp (or any reliable timestamp) from the stream and overlay it on the frame. However, I am unsure if I am extracting the correct timestamp.
Here is my current implementation:
import cv2
import multiprocessing as mp
from datetime import datetime
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
def process_stream(stream_type, rtsp_url):
if stream_type == "gstreamer":
gst_pipeline = (
f'rtspsrc location="{rtsp_url}" latency=0 '
'do-ptp-sync=true do-timestamp=true ! '
'rtph264depay ! h264parse ! avdec_h264 ! '
'videoconvert ! timeoverlay '
'time-mode="rtc-time" '
'halign=left valign=bottom '
'font-desc="Sans, 10" ! '
'appsink drop=true sync=false'
)
cap = cv2.VideoCapture(gst_pipeline, cv2.CAP_GSTREAMER)
window_name = "RTSP Stream (Camera Time)"
else:
cap = cv2.VideoCapture(rtsp_url)
window_name = "RTSP Stream (Regular)"
if not cap.isOpened():
print(f"Error: Could not open {stream_type} RTSP stream.")
return
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
while True:
ret, frame = cap.read()
if not ret:
print(f"Error: Failed to receive frame from {stream_type} stream.")
break
if stream_type == "gstreamer":
ntp_timestamp = cap.get(cv2.CAP_PROP_POS_MSEC)
if ntp_timestamp > 0:
cv2.putText(frame, f"NTP Timestamp: {ntp_timestamp:.2f}", (10, 100),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
frame = cv2.resize(frame, (960, 540))
cv2.imshow(window_name, frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyWindow(window_name)
def main():
rtsp_url = "rtsp://admin:@192.168.1.11:554" # Hikvision RTSP Stream
gst_process = mp.Process(target=process_stream, args=("gstreamer", rtsp_url))
gst_process.start()
gst_process.join()
if __name__ == "__main__":
mp.set_start_method('spawn') # Required for Windows compatibility
main()
My Questions:
- Am I correctly extracting the NTP timestamp using
cap.get(cv2.CAP_PROP_POS_MSEC)
? - If not, how can I reliably extract timestamps from the RTSP stream?
- Is there a better approach using GStreamer to retrieve and display timestamps?
I am working with an RTSP stream from a Hikvision camera, which has its internal time synchronized via NTP. I am trying to extract timestamps from the video frames using OpenCV and GStreamer. My goal is to retrieve the NTP timestamp (or any reliable timestamp) from the stream and overlay it on the frame. However, I am unsure if I am extracting the correct timestamp.
Here is my current implementation:
import cv2
import multiprocessing as mp
from datetime import datetime
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
def process_stream(stream_type, rtsp_url):
if stream_type == "gstreamer":
gst_pipeline = (
f'rtspsrc location="{rtsp_url}" latency=0 '
'do-ptp-sync=true do-timestamp=true ! '
'rtph264depay ! h264parse ! avdec_h264 ! '
'videoconvert ! timeoverlay '
'time-mode="rtc-time" '
'halign=left valign=bottom '
'font-desc="Sans, 10" ! '
'appsink drop=true sync=false'
)
cap = cv2.VideoCapture(gst_pipeline, cv2.CAP_GSTREAMER)
window_name = "RTSP Stream (Camera Time)"
else:
cap = cv2.VideoCapture(rtsp_url)
window_name = "RTSP Stream (Regular)"
if not cap.isOpened():
print(f"Error: Could not open {stream_type} RTSP stream.")
return
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
while True:
ret, frame = cap.read()
if not ret:
print(f"Error: Failed to receive frame from {stream_type} stream.")
break
if stream_type == "gstreamer":
ntp_timestamp = cap.get(cv2.CAP_PROP_POS_MSEC)
if ntp_timestamp > 0:
cv2.putText(frame, f"NTP Timestamp: {ntp_timestamp:.2f}", (10, 100),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
frame = cv2.resize(frame, (960, 540))
cv2.imshow(window_name, frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyWindow(window_name)
def main():
rtsp_url = "rtsp://admin:@192.168.1.11:554" # Hikvision RTSP Stream
gst_process = mp.Process(target=process_stream, args=("gstreamer", rtsp_url))
gst_process.start()
gst_process.join()
if __name__ == "__main__":
mp.set_start_method('spawn') # Required for Windows compatibility
main()
My Questions:
- Am I correctly extracting the NTP timestamp using
cap.get(cv2.CAP_PROP_POS_MSEC)
? - If not, how can I reliably extract timestamps from the RTSP stream?
- Is there a better approach using GStreamer to retrieve and display timestamps?
- you should use gstreamer directly, not via opencv. – Christoph Rackwitz Commented Mar 29 at 11:45
1 Answer
Reset to default 2See https://gstreamer.freedesktop./documentation/rtsp/rtspsrc.html?gi-language=c#rtspsrc:add-reference-timestamp-meta
You can set this option and rtspsrc will attach a meta object to buffers from where you can pull the NTP time from. This data will only be available once a NTP information has been send in stream (usually RTP SR).