admin管理员组

文章数量:1356245

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:

  1. Am I correctly extracting the NTP timestamp using cap.get(cv2.CAP_PROP_POS_MSEC)?
  2. If not, how can I reliably extract timestamps from the RTSP stream?
  3. 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:

  1. Am I correctly extracting the NTP timestamp using cap.get(cv2.CAP_PROP_POS_MSEC)?
  2. If not, how can I reliably extract timestamps from the RTSP stream?
  3. Is there a better approach using GStreamer to retrieve and display timestamps?
Share Improve this question edited Mar 28 at 10:51 Christoph Rackwitz 15.8k5 gold badges39 silver badges51 bronze badges asked Mar 28 at 5:52 deondmello16deondmello16 35 bronze badges 1
  • you should use gstreamer directly, not via opencv. – Christoph Rackwitz Commented Mar 29 at 11:45
Add a comment  | 

1 Answer 1

Reset to default 2

See 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).

本文标签: video streamingExtracting Timestamps from RTSP Stream with OpenCV and GStreamerStack Overflow